From 0e0a1e70b7ed0eb8d552d2c27dc9d1a43aa33233 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Tue, 8 Mar 2022 13:43:40 +0000
Subject: [PATCH 01/60] Extended WebUI, OpenConfig Driver support and
 functional test for OFC'22

---
 configure_dashboards.sh                       |   6 +-
 open_dashboard.sh                             |   4 +-
 open_webui.sh                                 |  23 ++-
 scripts/run_tests_locally-compute.sh          |  28 +++
 scripts/run_tests_locally-device.sh           |  28 +++
 scripts/run_tests_locally-service.sh          |  28 +++
 .../nbi_plugins/ietf_l2vpn/Constants.py       |  15 +-
 .../ietf_l2vpn/L2VPN_SiteNetworkAccesses.py   |  79 ++++++--
 src/compute/tests/Constants.py                |  18 +-
 src/device/service/MonitoringLoops.py         |   6 +-
 src/device/service/driver_api/_Driver.py      |   1 +
 .../drivers/openconfig/OpenConfigDriver.py    | 137 ++++++++++----
 .../drivers/openconfig/RetryDecorator.py      |  46 +++++
 .../drivers/openconfig/templates/EndPoints.py |   2 +-
 .../openconfig/templates/Interfaces.py        |   6 +-
 .../drivers/openconfig/templates/Namespace.py |   8 +
 .../openconfig/templates/NetworkInstances.py  |  81 +++++++-
 .../openconfig/templates/RoutingPolicy.py     |  85 +++++++++
 .../drivers/openconfig/templates/__init__.py  |   7 +-
 .../templates/interface/edit_config.xml       |   8 +-
 .../network_instance/edit_config.xml          |   2 +-
 .../inter_instance_policies/edit_config.xml   |  15 ++
 .../protocols/edit_config.xml                 |  27 +++
 .../table_connections/edit_config.xml         |  19 +-
 .../bgp_defined_set/edit_config.xml           |  14 ++
 .../templates/routing_policy/get.xml          |   8 +
 .../policy_definition/edit_config.xml         |  12 ++
 .../statement/edit_config.xml                 |  30 +++
 src/device/tests/test_unitary.py              |  22 ++-
 src/monitoring/service/__main__.py            |   4 +-
 .../L3NMEmulatedServiceHandler.py             | 173 ++++++++++++++++--
 .../L3NMOpenConfigServiceHandler.py           | 173 ++++++++++++++++--
 src/service/tests/ServiceHandler_L3NM_EMU.py  |  14 +-
 src/service/tests/ServiceHandler_L3NM_OC.py   |  19 +-
 src/start_webui_dev_mode.sh                   |   6 +-
 src/tests/ofc22/.gitignore                    |   2 +
 src/tests/ofc22/descriptors_emulated.json     | 108 +++++++++++
 src/tests/ofc22/redeploy_webui.sh             |  59 ++++++
 src/tests/ofc22/run_test_01_bootstrap.sh      |   4 +-
 src/tests/ofc22/run_test_02_create_service.sh |   3 +-
 src/tests/ofc22/run_test_03_delete_service.sh |   3 +-
 src/tests/ofc22/run_test_04_cleanup.sh        |   3 +-
 src/tests/ofc22/tests/BuildDescriptors.py     |  35 ++++
 src/tests/ofc22/tests/LoadDescriptors.py      |  40 ++++
 src/tests/ofc22/tests/Objects.py              |  36 ++--
 src/webui/Config.py                           |   1 +
 src/webui/Dockerfile                          |   2 +-
 src/webui/grafana_dashboard.json              |  34 ++--
 src/webui/service/__init__.py                 |  13 +-
 src/webui/service/__main__.py                 |   7 +-
 src/webui/service/device/routes.py            |  30 ++-
 src/webui/service/link/__init__.py            |   0
 src/webui/service/link/routes.py              |  37 ++++
 src/webui/service/main/forms.py               |  23 ++-
 src/webui/service/main/routes.py              |  90 ++++++++-
 src/webui/service/service/routes.py           |  36 +++-
 src/webui/service/static/partners.png         | Bin 76488 -> 200855 bytes
 src/webui/service/static/topology.js          | 148 +++++++++++++++
 .../topology_icons/Acknowledgements.txt       |  12 ++
 .../service/static/topology_icons/cloud.png   | Bin 0 -> 8988 bytes
 .../emu-optical-line-system.png               | Bin 0 -> 12869 bytes
 .../topology_icons/emu-packet-router.png      | Bin 0 -> 14197 bytes
 .../topology_icons/emu-packet-switch.png      | Bin 0 -> 11859 bytes
 .../topology_icons/optical-line-system.png    | Bin 0 -> 13777 bytes
 .../static/topology_icons/packet-router.png   | Bin 0 -> 16162 bytes
 .../static/topology_icons/packet-switch.png   | Bin 0 -> 9777 bytes
 src/webui/service/templates/base.html         |  52 ++++--
 src/webui/service/templates/device/add.html   |  13 +-
 .../service/templates/device/detail.html      |  46 +++--
 src/webui/service/templates/device/home.html  |   8 +-
 src/webui/service/templates/link/home.html    |  96 ++++++++++
 src/webui/service/templates/main/about.html   |   2 +-
 src/webui/service/templates/main/home.html    |  69 +++++--
 .../service/templates/service/detail.html     |  99 ++++++++++
 src/webui/service/templates/service/home.html |  24 +--
 75 files changed, 1994 insertions(+), 295 deletions(-)
 create mode 100755 scripts/run_tests_locally-compute.sh
 create mode 100755 scripts/run_tests_locally-device.sh
 create mode 100755 scripts/run_tests_locally-service.sh
 create mode 100644 src/device/service/drivers/openconfig/RetryDecorator.py
 create mode 100644 src/device/service/drivers/openconfig/templates/RoutingPolicy.py
 create mode 100644 src/device/service/drivers/openconfig/templates/network_instance/inter_instance_policies/edit_config.xml
 create mode 100644 src/device/service/drivers/openconfig/templates/network_instance/protocols/edit_config.xml
 create mode 100644 src/device/service/drivers/openconfig/templates/routing_policy/bgp_defined_set/edit_config.xml
 create mode 100644 src/device/service/drivers/openconfig/templates/routing_policy/get.xml
 create mode 100644 src/device/service/drivers/openconfig/templates/routing_policy/policy_definition/edit_config.xml
 create mode 100644 src/device/service/drivers/openconfig/templates/routing_policy/policy_definition/statement/edit_config.xml
 create mode 100644 src/tests/ofc22/.gitignore
 create mode 100644 src/tests/ofc22/descriptors_emulated.json
 create mode 100755 src/tests/ofc22/redeploy_webui.sh
 create mode 100644 src/tests/ofc22/tests/BuildDescriptors.py
 create mode 100644 src/tests/ofc22/tests/LoadDescriptors.py
 create mode 100644 src/webui/service/link/__init__.py
 create mode 100644 src/webui/service/link/routes.py
 create mode 100644 src/webui/service/static/topology.js
 create mode 100644 src/webui/service/static/topology_icons/Acknowledgements.txt
 create mode 100644 src/webui/service/static/topology_icons/cloud.png
 create mode 100644 src/webui/service/static/topology_icons/emu-optical-line-system.png
 create mode 100644 src/webui/service/static/topology_icons/emu-packet-router.png
 create mode 100644 src/webui/service/static/topology_icons/emu-packet-switch.png
 create mode 100644 src/webui/service/static/topology_icons/optical-line-system.png
 create mode 100644 src/webui/service/static/topology_icons/packet-router.png
 create mode 100644 src/webui/service/static/topology_icons/packet-switch.png
 create mode 100644 src/webui/service/templates/link/home.html
 create mode 100644 src/webui/service/templates/service/detail.html

diff --git a/configure_dashboards.sh b/configure_dashboards.sh
index e05d53b2a..4a32d76de 100755
--- a/configure_dashboards.sh
+++ b/configure_dashboards.sh
@@ -22,11 +22,15 @@ INFLUXDB_USER=$(kubectl --namespace $K8S_NAMESPACE get secrets influxdb-secrets
 INFLUXDB_PASSWORD=$(kubectl --namespace $K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_ADMIN_PASSWORD}' | base64 --decode)
 INFLUXDB_DATABASE=$(kubectl --namespace $K8S_NAMESPACE get secrets influxdb-secrets -o jsonpath='{.data.INFLUXDB_DB}' | base64 --decode)
 
-GRAFANA_HOSTNAME=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+# GRAFANA_HOSTNAME=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+# GRAFANA_HOSTNAME=`kubectl get service/webuiservice-public -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'`
+GRAFANA_HOSTNAME=`kubectl get nodes --selector=node-role.kubernetes.io/master -o jsonpath='{$.items[*].status.addresses[?(@.type=="InternalIP")].address}'`
 GRAFANA_PORT=$(kubectl get service webuiservice-public --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==3000)].nodePort}')
+#GRAFANA_PORT=`kubectl get service/webuiservice-public -n ${K8S_NAMESPACE} -o jsonpath='{.spec.ports[1].nodePort}'`
 GRAFANA_USERNAME="admin"
 GRAFANA_PASSWORD=${GRAFANA_PASSWORD:-"admin123+"}
 GRAFANA_URL="http://${GRAFANA_USERNAME}:${GRAFANA_PASSWORD}@${GRAFANA_HOSTNAME}:${GRAFANA_PORT}"
+echo "Connecting to grafana at URL: ${GRAFANA_URL}..."
 
 # Configure Grafana Admin Password
 # Ref: https://grafana.com/docs/grafana/latest/http_api/user/#change-password
diff --git a/open_dashboard.sh b/open_dashboard.sh
index 6f87b207c..8291a22c7 100755
--- a/open_dashboard.sh
+++ b/open_dashboard.sh
@@ -18,8 +18,8 @@
 
 K8S_NAMESPACE=${K8S_NAMESPACE:-'tf-dev'}
 
-GRAFANA_IP=`kubectl get service/webuiservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'`
-GRAFANA_PORT=`kubectl get service/webuiservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.ports[1].port}'`
+GRAFANA_IP=$(kubectl get service/webuiservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}')
+GRAFANA_PORT=$(kubectl get service webuiservice-public --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==3000)].nodePort}')
 URL=http://${GRAFANA_IP}:${GRAFANA_PORT}
 
 echo Opening Dashboard on URL ${URL}
diff --git a/open_webui.sh b/open_webui.sh
index bcb45ac17..e4dfdb709 100755
--- a/open_webui.sh
+++ b/open_webui.sh
@@ -14,13 +14,24 @@
 
 # this script opens the webui
 
-WEBUI_PROTO=`kubectl get service/webuiservice -n tf-dev -o jsonpath='{.spec.ports[0].name}'`
-WEBUI_IP=`kubectl get service/webuiservice -n tf-dev -o jsonpath='{.spec.clusterIP}'`
-WEBUI_PORT=`kubectl get service/webuiservice -n tf-dev -o jsonpath='{.spec.ports[0].port}'`
-URL=${WEBUI_PROTO}://${WEBUI_IP}:${WEBUI_PORT}
+K8S_NAMESPACE=${K8S_NAMESPACE:-'tf-dev'}
 
-echo Opening web UI on URL ${URL}
+WEBUI_SERVICE_NAME="webuiservice-public"
+WEBUI_PROTO=`kubectl get service ${WEBUI_SERVICE_NAME} -n ${K8S_NAMESPACE} -o jsonpath='{.spec.ports[0].name}'`
+WEBUI_IP=`kubectl get service ${WEBUI_SERVICE_NAME} -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'`
+# WEBUI_PORT=$(kubectl get service ${WEBUI_SERVICE_NAME} --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==8004)].nodePort}')
+WEBUI_PORT=8004
+# GRAFANA_PORT=$(kubectl get service ${WEBUI_SERVICE_NAME} --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==3000)].nodePort}')
+GRAFANA_PORT=3000
 
+# Open WebUI
+URL=${WEBUI_PROTO}://${WEBUI_IP}:${WEBUI_PORT}
+echo Opening web UI on URL ${URL}
 # curl -kL ${URL}
+python3 -m webbrowser ${URL}
 
-python3 -m webbrowser ${URL}
\ No newline at end of file
+# Open Dashboard
+URL=${WEBUI_PROTO}://${WEBUI_IP}:${GRAFANA_PORT}
+echo Opening Dashboard on URL ${URL}
+# curl -kL ${URL}
+python3 -m webbrowser ${URL}
diff --git a/scripts/run_tests_locally-compute.sh b/scripts/run_tests_locally-compute.sh
new file mode 100755
index 000000000..48ce6e232
--- /dev/null
+++ b/scripts/run_tests_locally-compute.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=service.log -o log_file_level=DEBUG
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    compute/tests/test_unitary.py
diff --git a/scripts/run_tests_locally-device.sh b/scripts/run_tests_locally-device.sh
new file mode 100755
index 000000000..ba6c0b6a5
--- /dev/null
+++ b/scripts/run_tests_locally-device.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    device/tests/test_unitary.py
diff --git a/scripts/run_tests_locally-service.sh b/scripts/run_tests_locally-service.sh
new file mode 100755
index 000000000..853eb9767
--- /dev/null
+++ b/scripts/run_tests_locally-service.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=service.log -o log_file_level=DEBUG
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    service/tests/test_unitary.py
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py
index 838dd664c..9420517e1 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py
@@ -12,6 +12,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-DEFAULT_MTU = 1512
+DEFAULT_MTU              = 1512
 DEFAULT_ADDRESS_FAMILIES = ['IPV4']
-DEFAULT_SUB_INTERFACE_INDEX = 0
+DEFAULT_BGP_AS           = 65000
+DEFAULT_BGP_ROUTE_TARGET = '{:d}:{:d}'.format(DEFAULT_BGP_AS, 333)
+
+# Bearer mappings:
+# device_uuid:endpoint_uuid => (
+#       device_uuid, endpoint_uuid, router_id, route_distinguisher, sub_if_index, address_ip, address_prefix)
+BEARER_MAPPINGS = {
+    'R1-INF:13/2/1': ('R1-INF', '13/2/1', '10.10.10.1', '65000:100', 400, '3.3.2.1', 24),
+    'R2-EMU:13/2/1': ('R2-EMU', '13/2/1', '12.12.12.1', '65000:120', 450, '3.4.2.1', 24),
+    'R3-INF:13/2/1': ('R3-INF', '13/2/1', '20.20.20.1', '65000:200', 500, '3.3.1.1', 24),
+    'R4-EMU:13/2/1': ('R4-EMU', '13/2/1', '22.22.22.1', '65000:220', 550, '3.4.1.1', 24),
+}
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py
index 5fa0fa88e..6811dadac 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py
@@ -29,7 +29,7 @@ from .schemas.site_network_access import SCHEMA_SITE_NETWORK_ACCESS
 from .tools.Authentication import HTTP_AUTH
 from .tools.HttpStatusCodes import HTTP_NOCONTENT, HTTP_SERVERERROR
 from .tools.Validator import validate_message
-from .Constants import DEFAULT_ADDRESS_FAMILIES, DEFAULT_MTU, DEFAULT_SUB_INTERFACE_INDEX
+from .Constants import BEARER_MAPPINGS, DEFAULT_ADDRESS_FAMILIES, DEFAULT_BGP_AS, DEFAULT_BGP_ROUTE_TARGET, DEFAULT_MTU
 
 LOGGER = logging.getLogger(__name__)
 
@@ -38,10 +38,11 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
     cvlan_id = site_network_access['connection']['tagged-interface']['dot1q-vlan-tagged']['cvlan-id']
     bearer_reference = site_network_access['bearer']['bearer-reference']
 
-    # Assume bearer_reference    = '<device_uuid>:<endpoint_uuid>:<router_id>'
-    # Assume route_distinguisher = 0:<cvlan_id>
-    device_uuid,endpoint_uuid,router_id = bearer_reference.split(':')
-    route_distinguisher = '0:{:d}'.format(cvlan_id)
+    mapping = BEARER_MAPPINGS.get(bearer_reference)
+    if mapping is None:
+        msg = 'Specified Bearer({:s}) is not configured.'
+        raise Exception(msg.format(str(bearer_reference)))
+    device_uuid,endpoint_uuid,router_id,route_distinguisher,sub_if_index,address_ip,address_prefix = mapping
 
     # pylint: disable=no-member
     service_id = ServiceId()
@@ -63,15 +64,9 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
         endpoint_id.endpoint_uuid.uuid = endpoint_uuid
 
     for config_rule in service.service_config.config_rules:                 # pylint: disable=no-member
-        if config_rule.resource_key != 'settings': continue
+        if config_rule.resource_key != '/settings': continue
         json_settings = json.loads(config_rule.resource_value)
 
-        if 'route_distinguisher' not in json_settings:                      # missing, add it
-            json_settings['route_distinguisher'] = route_distinguisher
-        elif json_settings['route_distinguisher'] != route_distinguisher:   # differs, raise exception
-            msg = 'Specified RouteDistinguisher({:s}) differs from Service RouteDistinguisher({:s})'
-            raise Exception(msg.format(str(json_settings['route_distinguisher']), str(route_distinguisher)))
-
         if 'mtu' not in json_settings:                                      # missing, add it
             json_settings['mtu'] = DEFAULT_MTU
         elif json_settings['mtu'] != DEFAULT_MTU:                           # differs, raise exception
@@ -84,20 +79,33 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
             msg = 'Specified AddressFamilies({:s}) differs from Service AddressFamilies({:s})'
             raise Exception(msg.format(str(json_settings['address_families']), str(DEFAULT_ADDRESS_FAMILIES)))
 
+        if 'bgp_as' not in json_settings:                                   # missing, add it
+            json_settings['bgp_as'] = DEFAULT_BGP_AS
+        elif json_settings['bgp_as'] != DEFAULT_BGP_AS:                     # differs, raise exception
+            msg = 'Specified BgpAs({:s}) differs from Service BgpAs({:s})'
+            raise Exception(msg.format(str(json_settings['bgp_as']), str(DEFAULT_BGP_AS)))
+
+        if 'bgp_route_target' not in json_settings:                         # missing, add it
+            json_settings['bgp_route_target'] = DEFAULT_BGP_ROUTE_TARGET
+        elif json_settings['bgp_route_target'] != DEFAULT_BGP_ROUTE_TARGET: # differs, raise exception
+            msg = 'Specified BgpRouteTarget({:s}) differs from Service BgpRouteTarget({:s})'
+            raise Exception(msg.format(str(json_settings['bgp_route_target']), str(DEFAULT_BGP_ROUTE_TARGET)))
+
         config_rule.resource_value = json.dumps(json_settings, sort_keys=True)
         break
     else:
         # not found, add it
         config_rule = service.service_config.config_rules.add()             # pylint: disable=no-member
         config_rule.action = ConfigActionEnum.CONFIGACTION_SET
-        config_rule.resource_key = 'settings'
+        config_rule.resource_key = '/settings'
         config_rule.resource_value = json.dumps({
-            'route_distinguisher': route_distinguisher,
-            'mtu': DEFAULT_MTU,
+            'mtu'             : DEFAULT_MTU,
             'address_families': DEFAULT_ADDRESS_FAMILIES,
+            'bgp_as'          : DEFAULT_BGP_AS,
+            'bgp_route_target': DEFAULT_BGP_ROUTE_TARGET,
         }, sort_keys=True)
 
-    endpoint_settings_key = 'device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
+    endpoint_settings_key = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
     for config_rule in service.service_config.config_rules:                 # pylint: disable=no-member
         if config_rule.resource_key != endpoint_settings_key: continue
         json_settings = json.loads(config_rule.resource_value)
@@ -108,12 +116,39 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
             msg = 'Specified RouterId({:s}) differs from Service RouterId({:s})'
             raise Exception(msg.format(str(json_settings['router_id']), str(router_id)))
 
+        if 'route_distinguisher' not in json_settings:                      # missing, add it
+            json_settings['route_distinguisher'] = route_distinguisher
+        elif json_settings['route_distinguisher'] != route_distinguisher:   # differs, raise exception
+            msg = 'Specified RouteDistinguisher({:s}) differs from Service RouteDistinguisher({:s})'
+            raise Exception(msg.format(str(json_settings['route_distinguisher']), str(route_distinguisher)))
+
         if 'sub_interface_index' not in json_settings:                      # missing, add it
-            json_settings['sub_interface_index'] = DEFAULT_SUB_INTERFACE_INDEX
-        elif json_settings['sub_interface_index'] != DEFAULT_SUB_INTERFACE_INDEX:   # differs, raise exception
+            json_settings['sub_interface_index'] = sub_if_index
+        elif json_settings['sub_interface_index'] != sub_if_index:   # differs, raise exception
             msg = 'Specified SubInterfaceIndex({:s}) differs from Service SubInterfaceIndex({:s})'
             raise Exception(msg.format(
-                str(json_settings['sub_interface_index']), str(DEFAULT_SUB_INTERFACE_INDEX)))
+                str(json_settings['sub_interface_index']), str(sub_if_index)))
+
+        if 'vlan_id' not in json_settings:                                  # missing, add it
+            json_settings['vlan_id'] = cvlan_id
+        elif json_settings['vlan_id'] != cvlan_id:                          # differs, raise exception
+            msg = 'Specified VLANId({:s}) differs from Service VLANId({:s})'
+            raise Exception(msg.format(
+                str(json_settings['vlan_id']), str(cvlan_id)))
+
+        if 'address_ip' not in json_settings:                               # missing, add it
+            json_settings['address_ip'] = address_ip
+        elif json_settings['address_ip'] != address_ip:                     # differs, raise exception
+            msg = 'Specified AddressIP({:s}) differs from Service AddressIP({:s})'
+            raise Exception(msg.format(
+                str(json_settings['address_ip']), str(address_ip)))
+
+        if 'address_prefix' not in json_settings:                           # missing, add it
+            json_settings['address_prefix'] = address_prefix
+        elif json_settings['address_prefix'] != address_prefix:             # differs, raise exception
+            msg = 'Specified AddressPrefix({:s}) differs from Service AddressPrefix({:s})'
+            raise Exception(msg.format(
+                str(json_settings['address_prefix']), str(address_prefix)))
 
         config_rule.resource_value = json.dumps(json_settings, sort_keys=True)
         break
@@ -124,7 +159,11 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
         config_rule.resource_key = endpoint_settings_key
         config_rule.resource_value = json.dumps({
             'router_id': router_id,
-            'sub_interface_index': DEFAULT_SUB_INTERFACE_INDEX,
+            'route_distinguisher': route_distinguisher,
+            'sub_interface_index': sub_if_index,
+            'vlan_id': cvlan_id,
+            'address_ip': address_ip,
+            'address_prefix': address_prefix,
         }, sort_keys=True)
 
     return service
diff --git a/src/compute/tests/Constants.py b/src/compute/tests/Constants.py
index ebe36eabc..8d4e2ba8f 100644
--- a/src/compute/tests/Constants.py
+++ b/src/compute/tests/Constants.py
@@ -22,7 +22,7 @@ WIM_MAPPING  = [
         #'device_interface_id' : ??,                # pop_switch_port
         'service_endpoint_id' : 'ep-1',             # wan_service_endpoint_id
         'service_mapping_info': {                   # wan_service_mapping_info, other extra info
-            'bearer': {'bearer-reference': 'dev-1:ep-1:10.0.0.1'},
+            'bearer': {'bearer-reference': 'R1-INF:13/2/1'},
             'site-id': '1',
         },
         #'switch_dpid'         : ??,                # wan_switch_dpid
@@ -34,7 +34,7 @@ WIM_MAPPING  = [
         #'device_interface_id' : ??,                # pop_switch_port
         'service_endpoint_id' : 'ep-2',             # wan_service_endpoint_id
         'service_mapping_info': {                   # wan_service_mapping_info, other extra info
-            'bearer': {'bearer-reference': 'dev-2:ep-2:10.0.0.2'},
+            'bearer': {'bearer-reference': 'R2-EMU:13/2/1'},
             'site-id': '2',
         },
         #'switch_dpid'         : ??,                # wan_switch_dpid
@@ -46,13 +46,25 @@ WIM_MAPPING  = [
         #'device_interface_id' : ??,                # pop_switch_port
         'service_endpoint_id' : 'ep-3',             # wan_service_endpoint_id
         'service_mapping_info': {                   # wan_service_mapping_info, other extra info
-            'bearer': {'bearer-reference': 'dev-3:ep-3:10.0.0.3'},
+            'bearer': {'bearer-reference': 'R3-INF:13/2/1'},
             'site-id': '3',
         },
         #'switch_dpid'         : ??,                # wan_switch_dpid
         #'switch_port'         : ??,                # wan_switch_port
         #'datacenter_id'       : ??,                # vim_account
     },
+    {
+        'device-id'           : 'dev-4',            # pop_switch_dpid
+        #'device_interface_id' : ??,                # pop_switch_port
+        'service_endpoint_id' : 'ep-4',             # wan_service_endpoint_id
+        'service_mapping_info': {                   # wan_service_mapping_info, other extra info
+            'bearer': {'bearer-reference': 'R4-EMU:13/2/1'},
+            'site-id': '4',
+        },
+        #'switch_dpid'         : ??,                # wan_switch_dpid
+        #'switch_port'         : ??,                # wan_switch_port
+        #'datacenter_id'       : ??,                # vim_account
+    },
 ]
 
 SERVICE_TYPE = 'ELINE'
diff --git a/src/device/service/MonitoringLoops.py b/src/device/service/MonitoringLoops.py
index 7cacabf23..e5b671f7f 100644
--- a/src/device/service/MonitoringLoops.py
+++ b/src/device/service/MonitoringLoops.py
@@ -126,9 +126,11 @@ class MonitoringLoops:
                 LOGGER.warning('Kpi({:s}) not found'.format(str_kpi_key))
                 continue
 
+            # FIXME: uint32 used for intVal results in out of range issues. Temporarily changed to float
+            #        extend the 'kpi_value' to support long integers (uint64 / int64 / ...)
             if isinstance(value, int):
-                kpi_value_field_name = 'intVal'
-                kpi_value_field_cast = int
+                kpi_value_field_name = 'floatVal'   # 'intVal'
+                kpi_value_field_cast = float        # int
             elif isinstance(value, float):
                 kpi_value_field_name = 'floatVal'
                 kpi_value_field_cast = float
diff --git a/src/device/service/driver_api/_Driver.py b/src/device/service/driver_api/_Driver.py
index 83462bb39..f30165a17 100644
--- a/src/device/service/driver_api/_Driver.py
+++ b/src/device/service/driver_api/_Driver.py
@@ -20,6 +20,7 @@ from typing import Any, Iterator, List, Optional, Tuple, Union
 RESOURCE_ENDPOINTS         = '__endpoints__'
 RESOURCE_INTERFACES        = '__interfaces__'
 RESOURCE_NETWORK_INSTANCES = '__network_instances__'
+RESOURCE_ROUTING_POLICIES  = '__routing_policies__'
 
 class _Driver:
     def __init__(self, address : str, port : int, **settings) -> None:
diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index 861186065..7f582c488 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -12,22 +12,24 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import anytree, logging, pytz, queue, re, threading
-import lxml.etree as ET
+import anytree, copy, logging, pytz, queue, re, threading
+#import lxml.etree as ET
 from datetime import datetime, timedelta
 from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
 from apscheduler.executors.pool import ThreadPoolExecutor
 from apscheduler.job import Job
 from apscheduler.jobstores.memory import MemoryJobStore
 from apscheduler.schedulers.background import BackgroundScheduler
-from netconf_client.connect import connect_ssh
+from netconf_client.connect import connect_ssh, Session
 from netconf_client.ncclient import Manager
+from common.tools.client.RetryDecorator import delay_exponential
 from common.type_checkers.Checkers import chk_length, chk_string, chk_type, chk_float
 from device.service.driver_api.Exceptions import UnsupportedResourceKeyException
 from device.service.driver_api._Driver import _Driver
-from device.service.driver_api.AnyTreeTools import TreeNode, dump_subtree, get_subnode, set_subnode_value
-from device.service.drivers.openconfig.Tools import xml_pretty_print, xml_to_dict, xml_to_file
-from device.service.drivers.openconfig.templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filter, parse
+from device.service.driver_api.AnyTreeTools import TreeNode, get_subnode, set_subnode_value #dump_subtree
+#from .Tools import xml_pretty_print, xml_to_dict, xml_to_file
+from .templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filter, parse
+from .RetryDecorator import retry
 
 DEBUG_MODE = False
 #logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
@@ -47,42 +49,109 @@ RE_GET_ENDPOINT_FROM_INTERFACE_XPATH = re.compile(r".*interface\[oci\:name\='([^
 SAMPLE_EVICTION_SECONDS = 30.0 # seconds
 SAMPLE_RESOURCE_KEY = 'interfaces/interface/state/counters'
 
+MAX_RETRIES = 15
+DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
+RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
+
+class NetconfSessionHandler:
+    def __init__(self, address : str, port : int, **settings) -> None:
+        self.__lock = threading.RLock()
+        self.__connected = threading.Event()
+        self.__address = address
+        self.__port = int(port)
+        self.__username = settings.get('username')
+        self.__password = settings.get('password')
+        self.__timeout = int(settings.get('timeout', 120))
+        self.__netconf_session : Session = None
+        self.__netconf_manager : Manager = None
+
+    def connect(self):
+        with self.__lock:
+            self.__netconf_session = connect_ssh(
+                host=self.__address, port=self.__port, username=self.__username, password=self.__password)
+            self.__netconf_manager = Manager(self.__netconf_session, timeout=self.__timeout)
+            self.__netconf_manager.set_logger_level(logging.DEBUG if DEBUG_MODE else logging.WARNING)
+            self.__connected.set()
+
+    def disconnect(self):
+        if not self.__connected.is_set(): return
+        with self.__lock:
+            self.__netconf_manager.close_session()
+
+    @RETRY_DECORATOR
+    def get(self, filter=None, with_defaults=None): # pylint: disable=redefined-builtin
+        with self.__lock:
+            return self.__netconf_manager.get(filter=filter, with_defaults=with_defaults)
+
+    @RETRY_DECORATOR
+    def edit_config(
+        self, config, target='running', default_operation=None, test_option=None,
+        error_option=None, format='xml'                                             # pylint: disable=redefined-builtin
+    ):
+        if config == EMPTY_CONFIG: return
+        with self.__lock:
+            self.__netconf_manager.edit_config(
+                config, target=target, default_operation=default_operation, test_option=test_option,
+                error_option=error_option, format=format)
+
+def compute_delta_sample(previous_sample, previous_timestamp, current_sample, current_timestamp):
+    if previous_sample is None: return None
+    if previous_timestamp is None: return None
+    if current_sample is None: return None
+    if current_timestamp is None: return None
+    delay = current_timestamp - previous_timestamp
+    field_keys = set(previous_sample.keys()).union(current_sample.keys())
+    field_keys.discard('name')
+    delta_sample = {'name': previous_sample['name']}
+    for field_key in field_keys:
+        previous_sample_value = previous_sample[field_key]
+        if not isinstance(previous_sample_value, (int, float)): continue
+        current_sample_value = current_sample[field_key]
+        if not isinstance(current_sample_value, (int, float)): continue
+        delta_value = current_sample_value - previous_sample_value
+        if delta_value < 0: continue
+        delta_sample[field_key] = delta_value / delay
+    return delta_sample
+
 class SamplesCache:
-    def __init__(self) -> None:
+    def __init__(self, netconf_handler : NetconfSessionHandler) -> None:
+        self.__netconf_handler = netconf_handler
         self.__lock = threading.Lock()
         self.__timestamp = None
-        self.__samples = {}
+        self.__absolute_samples = {}
+        self.__delta_samples = {}
 
-    def _refresh_samples(self, netconf_manager : Manager) -> None:
+    def _refresh_samples(self) -> None:
         with self.__lock:
             try:
                 now = datetime.timestamp(datetime.utcnow())
                 if self.__timestamp is not None and (now - self.__timestamp) < SAMPLE_EVICTION_SECONDS: return
                 str_filter = get_filter(SAMPLE_RESOURCE_KEY)
-                xml_data = netconf_manager.get(filter=str_filter).data_ele
+                xml_data = self.__netconf_handler.get(filter=str_filter).data_ele
                 interface_samples = parse(SAMPLE_RESOURCE_KEY, xml_data)
                 for interface,samples in interface_samples:
                     match = RE_GET_ENDPOINT_FROM_INTERFACE_KEY.match(interface)
                     if match is None: continue
                     interface = match.group(1)
-                    self.__samples[interface] = samples
+                    delta_sample = compute_delta_sample(
+                        self.__absolute_samples.get(interface), self.__timestamp, samples, now)
+                    if delta_sample is not None: self.__delta_samples[interface] = delta_sample
+                    self.__absolute_samples[interface] = samples
                 self.__timestamp = now
             except: # pylint: disable=bare-except
                 LOGGER.exception('Error collecting samples')
 
-    def get(self, resource_key : str, netconf_manager : Manager) -> Tuple[float, Dict]:
-        self._refresh_samples(netconf_manager)
+    def get(self, resource_key : str) -> Tuple[float, Dict]:
+        self._refresh_samples()
         match = RE_GET_ENDPOINT_FROM_INTERFACE_XPATH.match(resource_key)
         with self.__lock:
             if match is None: return self.__timestamp, {}
             interface = match.group(1)
-            return self.__timestamp, self.__samples.get(interface, {})
+            return self.__timestamp, copy.deepcopy(self.__delta_samples.get(interface, {}))
 
-def do_sampling(
-    netconf_manager : Manager, samples_cache : SamplesCache, resource_key : str, out_samples : queue.Queue
-) -> None:
+def do_sampling(samples_cache : SamplesCache, resource_key : str, out_samples : queue.Queue) -> None:
     try:
-        timestamp, samples = samples_cache.get(resource_key, netconf_manager)
+        timestamp, samples = samples_cache.get(resource_key)
         counter_name = resource_key.split('/')[-1].split(':')[-1]
         value = samples.get(counter_name)
         if value is None:
@@ -93,19 +162,14 @@ def do_sampling(
     except: # pylint: disable=bare-except
         LOGGER.exception('Error retrieving samples')
 
-
 class OpenConfigDriver(_Driver):
     def __init__(self, address : str, port : int, **settings) -> None: # pylint: disable=super-init-not-called
-        self.__address = address
-        self.__port = int(port)
-        self.__settings = settings
         self.__lock = threading.Lock()
         #self.__initial = TreeNode('.')
         #self.__running = TreeNode('.')
         self.__subscriptions = TreeNode('.')
         self.__started = threading.Event()
         self.__terminate = threading.Event()
-        self.__netconf_manager : Manager = None
         self.__scheduler = BackgroundScheduler(daemon=True) # scheduler used to emulate sampling events
         self.__scheduler.configure(
             jobstores = {'default': MemoryJobStore()},
@@ -113,18 +177,13 @@ class OpenConfigDriver(_Driver):
             job_defaults = {'coalesce': False, 'max_instances': 3},
             timezone=pytz.utc)
         self.__out_samples = queue.Queue()
-        self.__samples_cache = SamplesCache()
+        self.__netconf_handler : NetconfSessionHandler = NetconfSessionHandler(address, port, **settings)
+        self.__samples_cache = SamplesCache(self.__netconf_handler)
 
     def Connect(self) -> bool:
         with self.__lock:
             if self.__started.is_set(): return True
-            username = self.__settings.get('username')
-            password = self.__settings.get('password')
-            timeout = int(self.__settings.get('timeout', 120))
-            session = connect_ssh(
-                host=self.__address, port=self.__port, username=username, password=password)
-            self.__netconf_manager = Manager(session, timeout=timeout)
-            self.__netconf_manager.set_logger_level(logging.DEBUG if DEBUG_MODE else logging.WARNING)
+            self.__netconf_handler.connect()
             # Connect triggers activation of sampling events that will be scheduled based on subscriptions
             self.__scheduler.start()
             self.__started.set()
@@ -138,7 +197,7 @@ class OpenConfigDriver(_Driver):
             if not self.__started.is_set(): return True
             # Disconnect triggers deactivation of sampling events
             self.__scheduler.shutdown()
-            self.__netconf_manager.close_session()
+            self.__netconf_handler.disconnect()
             return True
 
     def GetInitialConfig(self) -> List[Tuple[str, Any]]:
@@ -155,8 +214,9 @@ class OpenConfigDriver(_Driver):
                 try:
                     chk_string(str_resource_name, resource_key, allow_empty=False)
                     str_filter = get_filter(resource_key)
+                    LOGGER.info('[GetConfig] str_filter = {:s}'.format(str(str_filter)))
                     if str_filter is None: str_filter = resource_key
-                    xml_data = self.__netconf_manager.get(filter=str_filter).data_ele
+                    xml_data = self.__netconf_handler.get(filter=str_filter).data_ele
                     if isinstance(xml_data, Exception): raise xml_data
                     results.extend(parse(resource_key, xml_data))
                 except Exception as e: # pylint: disable=broad-except
@@ -182,8 +242,7 @@ class OpenConfigDriver(_Driver):
                     if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
                     LOGGER.info('[SetConfig] str_config_message[{:d}] = {:s}'.format(
                         len(str_config_message), str(str_config_message)))
-                    if str_config_message != EMPTY_CONFIG:
-                        self.__netconf_manager.edit_config(str_config_message, target='running')
+                    self.__netconf_handler.edit_config(str_config_message, target='running')
                     results.append(True)
                 except Exception as e: # pylint: disable=broad-except
                     LOGGER.exception('Exception setting {:s}: {:s}'.format(str_resource_name, str(resource)))
@@ -208,9 +267,7 @@ class OpenConfigDriver(_Driver):
                     if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
                     LOGGER.info('[DeleteConfig] str_config_message[{:d}] = {:s}'.format(
                         len(str_config_message), str(str_config_message)))
-                    if str_config_message != EMPTY_CONFIG:
-                        self.__netconf_manager.edit_config(str_config_message, target='running')
-                    self.__netconf_manager.edit_config(str_config_message, target='running')
+                    self.__netconf_handler.edit_config(str_config_message, target='running')
                     results.append(True)
                 except Exception as e: # pylint: disable=broad-except
                     LOGGER.exception('Exception deleting {:s}: {:s}'.format(str_resource_name, str(resource_key)))
@@ -239,13 +296,13 @@ class OpenConfigDriver(_Driver):
                     continue
 
                 start_date,end_date = None,None
-                if sampling_duration <= 1.e-12:
+                if sampling_duration >= 1.e-12:
                     start_date = datetime.utcnow()
                     end_date = start_date + timedelta(seconds=sampling_duration)
 
                 job_id = 'k={:s}/d={:f}/i={:f}'.format(resource_key, sampling_duration, sampling_interval)
                 job = self.__scheduler.add_job(
-                    do_sampling, args=(self.__netconf_manager, self.__samples_cache, resource_key, self.__out_samples),
+                    do_sampling, args=(self.__samples_cache, resource_key, self.__out_samples),
                     kwargs={}, id=job_id, trigger='interval', seconds=sampling_interval,
                     start_date=start_date, end_date=end_date, timezone=pytz.utc)
 
diff --git a/src/device/service/drivers/openconfig/RetryDecorator.py b/src/device/service/drivers/openconfig/RetryDecorator.py
new file mode 100644
index 000000000..d8ccddb4d
--- /dev/null
+++ b/src/device/service/drivers/openconfig/RetryDecorator.py
@@ -0,0 +1,46 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, time
+from common.tools.client.RetryDecorator import delay_linear
+
+LOGGER = logging.getLogger(__name__)
+
+def retry(max_retries=0, delay_function=delay_linear(initial=0, increment=0),
+          prepare_method_name=None, prepare_method_args=[], prepare_method_kwargs={}):
+    def _reconnect(func):
+        def wrapper(self, *args, **kwargs):
+            if prepare_method_name is not None:
+                prepare_method = getattr(self, prepare_method_name, None)
+                if prepare_method is None: raise Exception('Prepare Method ({}) not found'.format(prepare_method_name))
+            num_try, given_up = 0, False
+            while not given_up:
+                try:
+                    return func(self, *args, **kwargs)
+                except OSError as e:
+                    if str(e) != 'Socket is closed': raise
+
+                    num_try += 1
+                    given_up = num_try > max_retries
+                    if given_up: raise Exception('Giving up... {:d} tries failed'.format(max_retries)) from e
+                    if delay_function is not None:
+                        delay = delay_function(num_try)
+                        time.sleep(delay)
+                        LOGGER.info('Retry {:d}/{:d} after {:f} seconds...'.format(num_try, max_retries, delay))
+                    else:
+                        LOGGER.info('Retry {:d}/{:d} immediate...'.format(num_try, max_retries))
+
+                    if prepare_method_name is not None: prepare_method(*prepare_method_args, **prepare_method_kwargs)
+        return wrapper
+    return _reconnect
diff --git a/src/device/service/drivers/openconfig/templates/EndPoints.py b/src/device/service/drivers/openconfig/templates/EndPoints.py
index 192d0b3de..c11b1669d 100644
--- a/src/device/service/drivers/openconfig/templates/EndPoints.py
+++ b/src/device/service/drivers/openconfig/templates/EndPoints.py
@@ -47,5 +47,5 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
         add_value_from_collection(endpoint, 'sample_types', sample_types)
 
         if len(endpoint) == 0: continue
-        response.append(('endpoint[{:s}]'.format(endpoint['uuid']), endpoint))
+        response.append(('/endpoint[{:s}]'.format(endpoint['uuid']), endpoint))
     return response
diff --git a/src/device/service/drivers/openconfig/templates/Interfaces.py b/src/device/service/drivers/openconfig/templates/Interfaces.py
index 5044ff16f..33f977524 100644
--- a/src/device/service/drivers/openconfig/templates/Interfaces.py
+++ b/src/device/service/drivers/openconfig/templates/Interfaces.py
@@ -81,11 +81,11 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
             #add_value_from_collection(subinterface, 'ipv4_addresses', ipv4_addresses)
 
             if len(subinterface) == 0: continue
-            resource_key = 'interface[{:s}]/subinterface[{:s}]'.format(interface['name'], str(subinterface['index']))
+            resource_key = '/interface[{:s}]/subinterface[{:s}]'.format(interface['name'], str(subinterface['index']))
             response.append((resource_key, subinterface))
 
         if len(interface) == 0: continue
-        response.append(('interface[{:s}]'.format(interface['name']), interface))
+        response.append(('/interface[{:s}]'.format(interface['name']), interface))
 
     return response
 
@@ -124,6 +124,6 @@ def parse_counters(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
         #LOGGER.info('[parse_counters] interface = {:s}'.format(str(interface)))
 
         if len(interface) == 0: continue
-        response.append(('interface[{:s}]'.format(interface['name']), interface))
+        response.append(('/interface[{:s}]'.format(interface['name']), interface))
 
     return response
diff --git a/src/device/service/drivers/openconfig/templates/Namespace.py b/src/device/service/drivers/openconfig/templates/Namespace.py
index a557adf79..35be5827d 100644
--- a/src/device/service/drivers/openconfig/templates/Namespace.py
+++ b/src/device/service/drivers/openconfig/templates/Namespace.py
@@ -15,6 +15,7 @@
 
 NAMESPACE_NETCONF       = 'urn:ietf:params:xml:ns:netconf:base:1.0'
 
+NAMESPACE_BGP_POLICY             = 'http://openconfig.net/yang/bgp-policy'
 NAMESPACE_INTERFACES             = 'http://openconfig.net/yang/interfaces'
 NAMESPACE_INTERFACES_IP          = 'http://openconfig.net/yang/interfaces/ip'
 NAMESPACE_NETWORK_INSTANCE       = 'http://openconfig.net/yang/network-instance'
@@ -22,10 +23,14 @@ NAMESPACE_NETWORK_INSTANCE_TYPES = 'http://openconfig.net/yang/network-instance-
 NAMESPACE_OPENCONFIG_TYPES       = 'http://openconfig.net/yang/openconfig-types'
 NAMESPACE_PLATFORM               = 'http://openconfig.net/yang/platform'
 NAMESPACE_PLATFORM_PORT          = 'http://openconfig.net/yang/platform/port'
+NAMESPACE_POLICY_TYPES           = 'http://openconfig.net/yang/policy-types'
+NAMESPACE_POLICY_TYPES_2         = 'http://openconfig.net/yang/policy_types'
+NAMESPACE_ROUTING_POLICY         = 'http://openconfig.net/yang/routing-policy'
 NAMESPACE_VLAN                   = 'http://openconfig.net/yang/vlan'
 
 NAMESPACES = {
     'nc'   : NAMESPACE_NETCONF,
+    'ocbp' : NAMESPACE_BGP_POLICY,
     'oci'  : NAMESPACE_INTERFACES,
     'ociip': NAMESPACE_INTERFACES_IP,
     'ocni' : NAMESPACE_NETWORK_INSTANCE,
@@ -33,5 +38,8 @@ NAMESPACES = {
     'ococt': NAMESPACE_OPENCONFIG_TYPES,
     'ocp'  : NAMESPACE_PLATFORM,
     'ocpp' : NAMESPACE_PLATFORM_PORT,
+    'ocpt' : NAMESPACE_POLICY_TYPES,
+    'ocpt2': NAMESPACE_POLICY_TYPES_2,
+    'ocrp' : NAMESPACE_ROUTING_POLICY,
     'ocv'  : NAMESPACE_VLAN,
 }
diff --git a/src/device/service/drivers/openconfig/templates/NetworkInstances.py b/src/device/service/drivers/openconfig/templates/NetworkInstances.py
index 647647022..b091a0d20 100644
--- a/src/device/service/drivers/openconfig/templates/NetworkInstances.py
+++ b/src/device/service/drivers/openconfig/templates/NetworkInstances.py
@@ -20,6 +20,12 @@ from .Tools import add_value_from_collection, add_value_from_tag
 LOGGER = logging.getLogger(__name__)
 
 XPATH_NETWORK_INSTANCES = "//ocni:network-instances/ocni:network-instance"
+XPATH_NI_PROTOCOLS      = ".//ocni:protocols/ocni:protocol"
+XPATH_NI_TABLE_CONNECTS = ".//ocni:table-connections/ocni:table-connection"
+
+XPATH_NI_IIP_AP         = ".//ocni:inter-instance-policies/ocni:apply-policy"
+XPATH_NI_IIP_AP_IMPORT  = ".//ocni:config/ocni:import-policy"
+XPATH_NI_IIP_AP_EXPORT  = ".//ocni:config/ocni:export-policy"
 
 def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
     response = []
@@ -45,5 +51,78 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
         #add_value_from_collection(network_instance, 'address_families', ni_address_families)
 
         if len(network_instance) == 0: continue
-        response.append(('network_instance[{:s}]'.format(network_instance['name']), network_instance))
+        response.append(('/network_instance[{:s}]'.format(network_instance['name']), network_instance))
+
+        for xml_protocol in xml_network_instance.xpath(XPATH_NI_PROTOCOLS, namespaces=NAMESPACES):
+            #LOGGER.info('xml_protocol = {:s}'.format(str(ET.tostring(xml_protocol))))
+
+            protocol = {}
+            add_value_from_tag(protocol, 'name', ni_name)
+
+            identifier = xml_protocol.find('ocni:identifier', namespaces=NAMESPACES)
+            if identifier is None: identifier = xml_protocol.find('ocpt:identifier', namespaces=NAMESPACES)
+            if identifier is None: identifier = xml_protocol.find('ocpt2:identifier', namespaces=NAMESPACES)
+            if identifier is None or identifier.text is None: continue
+            add_value_from_tag(protocol, 'identifier', identifier, cast=lambda s: s.replace('oc-pol-types:', ''))
+
+            name = xml_protocol.find('ocni:name', namespaces=NAMESPACES)
+            add_value_from_tag(protocol, 'protocol_name', name)
+
+            if protocol['identifier'] == 'BGP':
+                bgp_as = xml_protocol.find('ocni:bgp/ocni:global/ocni:config/ocni:as', namespaces=NAMESPACES)
+                add_value_from_tag(protocol, 'as', bgp_as, cast=int)
+
+            resource_key = '/network_instance[{:s}]/protocols[{:s}]'.format(
+                network_instance['name'], protocol['identifier'])
+            response.append((resource_key, protocol))
+
+        for xml_table_connection in xml_network_instance.xpath(XPATH_NI_TABLE_CONNECTS, namespaces=NAMESPACES):
+            #LOGGER.info('xml_table_connection = {:s}'.format(str(ET.tostring(xml_table_connection))))
+
+            table_connection = {}
+            add_value_from_tag(table_connection, 'name', ni_name)
+
+            src_protocol = xml_table_connection.find('ocni:src-protocol', namespaces=NAMESPACES)
+            add_value_from_tag(table_connection, 'src_protocol', src_protocol,
+                               cast=lambda s: s.replace('oc-pol-types:', ''))
+
+            dst_protocol = xml_table_connection.find('ocni:dst-protocol', namespaces=NAMESPACES)
+            add_value_from_tag(table_connection, 'dst_protocol', dst_protocol,
+                               cast=lambda s: s.replace('oc-pol-types:', ''))
+
+            address_family = xml_table_connection.find('ocni:address-family', namespaces=NAMESPACES)
+            add_value_from_tag(table_connection, 'address_family', address_family,
+                               cast=lambda s: s.replace('oc-types:', ''))
+
+            default_import_policy = xml_table_connection.find('ocni:default-import-policy', namespaces=NAMESPACES)
+            add_value_from_tag(table_connection, 'default_import_policy', default_import_policy)
+
+            resource_key = '/network_instance[{:s}]/table_connections[{:s}][{:s}][{:s}]'.format(
+                network_instance['name'], table_connection['src_protocol'], table_connection['dst_protocol'],
+                table_connection['address_family'])
+            response.append((resource_key, table_connection))
+
+        for xml_iip_ap in xml_network_instance.xpath(XPATH_NI_IIP_AP, namespaces=NAMESPACES):
+            #LOGGER.info('xml_iip_ap = {:s}'.format(str(ET.tostring(xml_iip_ap))))
+
+            for xml_import_policy in xml_iip_ap.xpath(XPATH_NI_IIP_AP_IMPORT, namespaces=NAMESPACES):
+                #LOGGER.info('xml_import_policy = {:s}'.format(str(ET.tostring(xml_import_policy))))
+                if xml_import_policy.text is None: continue
+                iip_ap = {}
+                add_value_from_tag(iip_ap, 'name', ni_name)
+                add_value_from_tag(iip_ap, 'import_policy', xml_import_policy)
+                resource_key = '/network_instance[{:s}]/inter_instance_policies[{:s}]'.format(
+                    iip_ap['name'], iip_ap['import_policy'])
+                response.append((resource_key, iip_ap))
+
+            for xml_export_policy in xml_iip_ap.xpath(XPATH_NI_IIP_AP_EXPORT, namespaces=NAMESPACES):
+                #LOGGER.info('xml_export_policy = {:s}'.format(str(ET.tostring(xml_export_policy))))
+                if xml_export_policy.text is None: continue
+                iip_ap = {}
+                add_value_from_tag(iip_ap, 'name', ni_name)
+                add_value_from_tag(iip_ap, 'export_policy', xml_export_policy)
+                resource_key = '/network_instance[{:s}]/inter_instance_policies[{:s}]'.format(
+                    iip_ap['name'], iip_ap['export_policy'])
+                response.append((resource_key, iip_ap))
+
     return response
diff --git a/src/device/service/drivers/openconfig/templates/RoutingPolicy.py b/src/device/service/drivers/openconfig/templates/RoutingPolicy.py
new file mode 100644
index 000000000..aae848370
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/RoutingPolicy.py
@@ -0,0 +1,85 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy, logging, lxml.etree as ET
+from typing import Any, Dict, List, Tuple
+from .Namespace import NAMESPACES
+from .Tools import add_value_from_collection, add_value_from_tag
+
+LOGGER = logging.getLogger(__name__)
+
+XPATH_POLICY_DEFINITIONS = "//ocrp:routing-policy/ocrp:policy-definitions/ocrp:policy-definition"
+XPATH_PD_STATEMENTS      = ".//ocrp:statements/ocrp:statement"
+XPATH_PD_ST_CONDITIONS   = ".//ocrp:conditions/ocbp:bgp-conditions/ocbp:match-ext-community-set"
+XPATH_PD_ST_ACTIONS      = ".//ocrp:actions"
+
+XPATH_BGP_EXT_COMMUN_SET = "//ocrp:routing-policy/ocrp:defined-sets/ocbp:bgp-defined-sets/" + \
+                           "ocbp:ext-community-sets/ocbp:ext-community-set"
+
+def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
+    #LOGGER.info('[RoutePolicy] xml_data = {:s}'.format(str(ET.tostring(xml_data))))
+
+    response = []
+    for xml_policy_definition in xml_data.xpath(XPATH_POLICY_DEFINITIONS, namespaces=NAMESPACES):
+        #LOGGER.info('xml_policy_definition = {:s}'.format(str(ET.tostring(xml_policy_definition))))
+
+        policy_definition = {}
+
+        policy_name = xml_policy_definition.find('ocrp:name', namespaces=NAMESPACES)
+        if policy_name is None or policy_name.text is None: continue
+        add_value_from_tag(policy_definition, 'policy_name', policy_name)
+
+        resource_key = '/routing_policy/policy_definition[{:s}]'.format(policy_definition['policy_name'])
+        response.append((resource_key, copy.deepcopy(policy_definition)))
+
+        for xml_statement in xml_policy_definition.xpath(XPATH_PD_STATEMENTS, namespaces=NAMESPACES):
+            statement_name = xml_statement.find('ocrp:name', namespaces=NAMESPACES)
+            add_value_from_tag(policy_definition, 'statement_name', statement_name)
+
+            for xml_condition in xml_statement.xpath(XPATH_PD_ST_CONDITIONS, namespaces=NAMESPACES):
+                ext_community_set_name = xml_condition.find('ocbp:config/ocbp:ext-community-set', namespaces=NAMESPACES)
+                add_value_from_tag(policy_definition, 'ext_community_set_name', ext_community_set_name)
+
+                match_set_options = xml_condition.find('ocbp:config/ocbp:match-set-options', namespaces=NAMESPACES)
+                add_value_from_tag(policy_definition, 'match_set_options', match_set_options)
+
+            for xml_action in xml_statement.xpath(XPATH_PD_ST_ACTIONS, namespaces=NAMESPACES):
+                policy_result = xml_action.find('ocbp:config/ocbp:policy-result', namespaces=NAMESPACES)
+                add_value_from_tag(policy_definition, 'policy_result', policy_result)
+
+        resource_key = '/routing_policy/policy_definition[{:s}]/statement[{:s}]'.format(
+            policy_definition['policy_name'], policy_definition['statement_name'])
+        response.append((resource_key, copy.deepcopy(policy_definition)))
+
+    for xml_bgp_ext_community_set in xml_data.xpath(XPATH_BGP_EXT_COMMUN_SET, namespaces=NAMESPACES):
+        #LOGGER.info('xml_bgp_ext_community_set = {:s}'.format(str(ET.tostring(xml_bgp_ext_community_set))))
+
+        bgp_ext_community_set = {}
+
+        ext_community_set_name = xml_bgp_ext_community_set.find('ocbp:ext-community-set-name', namespaces=NAMESPACES)
+        if ext_community_set_name is None or ext_community_set_name.text is None: continue
+        add_value_from_tag(bgp_ext_community_set, 'ext_community_set_name', ext_community_set_name)
+
+        resource_key = '/routing_policy/bgp_defined_set[{:s}]'.format(bgp_ext_community_set['ext_community_set_name'])
+        response.append((resource_key, copy.deepcopy(bgp_ext_community_set)))
+
+        ext_community_member = xml_bgp_ext_community_set.find('ocbp:ext-community-member', namespaces=NAMESPACES)
+        if ext_community_member is not None and ext_community_member.text is not None:
+            add_value_from_tag(bgp_ext_community_set, 'ext_community_member', ext_community_member)
+
+            resource_key = '/routing_policy/bgp_defined_set[{:s}][{:s}]'.format(
+                bgp_ext_community_set['ext_community_set_name'], bgp_ext_community_set['ext_community_member'])
+            response.append((resource_key, copy.deepcopy(bgp_ext_community_set)))
+
+    return response
diff --git a/src/device/service/drivers/openconfig/templates/__init__.py b/src/device/service/drivers/openconfig/templates/__init__.py
index da1426fd1..eb7842ea8 100644
--- a/src/device/service/drivers/openconfig/templates/__init__.py
+++ b/src/device/service/drivers/openconfig/templates/__init__.py
@@ -15,14 +15,17 @@
 import json, logging, lxml.etree as ET, re
 from typing import Any, Dict
 from jinja2 import Environment, PackageLoader, select_autoescape
-from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES
+from device.service.driver_api._Driver import (
+    RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES, RESOURCE_ROUTING_POLICIES)
 from .EndPoints import parse as parse_endpoints
 from .Interfaces import parse as parse_interfaces, parse_counters
 from .NetworkInstances import parse as parse_network_instances
+from .RoutingPolicy import parse as parse_routing_policy
 
 ALL_RESOURCE_KEYS = [
     RESOURCE_ENDPOINTS,
     RESOURCE_INTERFACES,
+    RESOURCE_ROUTING_POLICIES,      # routing policies should come before network instances
     RESOURCE_NETWORK_INSTANCES,
 ]
 
@@ -30,12 +33,14 @@ RESOURCE_KEY_MAPPINGS = {
     RESOURCE_ENDPOINTS        : 'component',
     RESOURCE_INTERFACES       : 'interface',
     RESOURCE_NETWORK_INSTANCES: 'network_instance',
+    RESOURCE_ROUTING_POLICIES : 'routing_policy',
 }
 
 RESOURCE_PARSERS = {
     'component'       : parse_endpoints,
     'interface'       : parse_interfaces,
     'network_instance': parse_network_instances,
+    'routing_policy'  : parse_routing_policy,
     'interfaces/interface/state/counters': parse_counters,
 }
 
diff --git a/src/device/service/drivers/openconfig/templates/interface/edit_config.xml b/src/device/service/drivers/openconfig/templates/interface/edit_config.xml
index ae29586a6..ff15d1d68 100644
--- a/src/device/service/drivers/openconfig/templates/interface/edit_config.xml
+++ b/src/device/service/drivers/openconfig/templates/interface/edit_config.xml
@@ -1,12 +1,14 @@
 <interfaces xmlns="http://openconfig.net/yang/interfaces">
-    <interface{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+    <interface{% if operation is defined and operation != 'delete' %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
         <name>{{name}}</name>
-        {% if operation is not defined or operation != 'delete' %}
         <config>
             <name>{{name}}</name>
+            {% if operation is defined and operation == 'delete' %}
+            <description></description>
+            {% else %}
             <description>{{description}}</description>
             <mtu>{{mtu}}</mtu>
+            {% endif %}
         </config>
-        {% endif %}
     </interface>
 </interfaces>
diff --git a/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml
index a8ceaac8f..9362c09c6 100644
--- a/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml
+++ b/src/device/service/drivers/openconfig/templates/network_instance/edit_config.xml
@@ -6,6 +6,7 @@
             <name>{{name}}</name>
             <type xmlns:oc-ni-types="http://openconfig.net/yang/network-instance-types">oc-ni-types:{{type}}</type>
             <description>{{description}}</description>
+            {% if router_id is defined %}<router-id>{{router_id}}</router-id>{% endif %}
             <route-distinguisher>{{route_distinguisher}}</route-distinguisher>
             <enabled>true</enabled>
         </config>
@@ -17,4 +18,3 @@
         {% endif %}
     </network-instance>
 </network-instances>
-
diff --git a/src/device/service/drivers/openconfig/templates/network_instance/inter_instance_policies/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/inter_instance_policies/edit_config.xml
new file mode 100644
index 000000000..b7c87c7ab
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/network_instance/inter_instance_policies/edit_config.xml
@@ -0,0 +1,15 @@
+{% if operation is not defined or operation != 'delete' %}
+<network-instances xmlns="http://openconfig.net/yang/network-instance">
+    <network-instance>
+        <name>{{name}}</name>
+        <inter-instance-policies>
+            <apply-policy>
+                <config>
+                    {% if import_policy is defined %}<import-policy>{{import_policy}}</import-policy>{% endif%}
+                    {% if export_policy is defined %}<export-policy>{{export_policy}}</export-policy>{% endif%}
+                </config>
+            </apply-policy>
+        </inter-instance-policies>
+    </network-instance>
+</network-instances>
+{% endif %}
diff --git a/src/device/service/drivers/openconfig/templates/network_instance/protocols/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/protocols/edit_config.xml
new file mode 100644
index 000000000..da05d0467
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/network_instance/protocols/edit_config.xml
@@ -0,0 +1,27 @@
+<network-instances xmlns="http://openconfig.net/yang/network-instance">
+    <network-instance>
+        <name>{{name}}</name>
+        <protocols>
+            <protocol{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+                <identifier>{{identifier}}</identifier>
+                <name>{{protocol_name}}</name>
+                {% if operation is not defined or operation != 'delete' %}
+                <config>
+                    <identifier>{{identifier}}</identifier>
+                    <name>{{protocol_name}}</name>
+                    <enabled>true</enabled>
+                </config>
+                {% if identifier=='BGP' %}
+                <bgp>
+                    <global>
+                        <config>
+                            <as>{{as}}</as>
+                        </config>
+                    </global>
+                </bgp>
+                {% endif %}
+                {% endif %}
+            </protocol>
+        </protocols>
+    </network-instance>
+</network-instances>
diff --git a/src/device/service/drivers/openconfig/templates/network_instance/table_connections/edit_config.xml b/src/device/service/drivers/openconfig/templates/network_instance/table_connections/edit_config.xml
index 751b3a1bd..46bf5e387 100644
--- a/src/device/service/drivers/openconfig/templates/network_instance/table_connections/edit_config.xml
+++ b/src/device/service/drivers/openconfig/templates/network_instance/table_connections/edit_config.xml
@@ -1,19 +1,20 @@
-{% if operation is not defined or operation != 'delete' %}
 <network-instances xmlns="http://openconfig.net/yang/network-instance">
     <network-instance>
         <name>{{name}}</name>
         <table-connections>
-            <table-connection>
-                <src-protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</src-protocol>
-                <dst-protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</dst-protocol>
-                <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
+            <table-connection{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+                <src-protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:{{src_protocol}}</src-protocol>
+                <dst-protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:{{dst_protocol}}</dst-protocol>
+                <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:{{address_family}}</address-family>
+                {% if operation is not defined or operation != 'delete' %}
                 <config>
-                    <src-protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:DIRECTLY_CONNECTED</src-protocol>
-                    <dst-protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:BGP</dst-protocol>
-                    <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:IPV4</address-family>
+                    <src-protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:{{src_protocol}}</src-protocol>
+                    <dst-protocol xmlns:oc-pol-types="http://openconfig.net/yang/policy-types">oc-pol-types:{{dst_protocol}}</dst-protocol>
+                    <address-family xmlns:oc-types="http://openconfig.net/yang/openconfig-types">oc-types:{{address_family}}</address-family>
+                    {% if default_import_policy is defined %}<default-import-policy>{{default_import_policy}}</default-import-policy>{% endif %}
                 </config>
+                {% endif %}
             </table-connection>
         </table-connections>
     </network-instance>
 </network-instances>
-{% endif %}
diff --git a/src/device/service/drivers/openconfig/templates/routing_policy/bgp_defined_set/edit_config.xml b/src/device/service/drivers/openconfig/templates/routing_policy/bgp_defined_set/edit_config.xml
new file mode 100644
index 000000000..df64606ae
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/routing_policy/bgp_defined_set/edit_config.xml
@@ -0,0 +1,14 @@
+<routing-policy xmlns="http://openconfig.net/yang/routing-policy">
+    <defined-sets>
+        <bgp-defined-sets xmlns="http://openconfig.net/yang/bgp-policy">
+            <ext-community-sets>
+                <ext-community-set{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+                    <ext-community-set-name>{{ext_community_set_name}}</ext-community-set-name>
+                    {% if operation is not defined or operation != 'delete' %}
+                    {% if ext_community_member is defined %} <ext-community-member>{{ext_community_member}}</ext-community-member>{% endif %}
+                    {% endif %}
+                </ext-community-set>
+            </ext-community-sets>
+        </bgp-defined-sets>
+    </defined-sets>
+</routing-policy>
diff --git a/src/device/service/drivers/openconfig/templates/routing_policy/get.xml b/src/device/service/drivers/openconfig/templates/routing_policy/get.xml
new file mode 100644
index 000000000..797e97026
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/routing_policy/get.xml
@@ -0,0 +1,8 @@
+<routing-policy xmlns="http://openconfig.net/yang/routing-policy">
+    <policy-definitions/>
+    <defined-sets>
+        <bgp-defined-sets xmlns="http://openconfig.net/yang/bgp-policy">
+            <ext-community-sets/>
+        </bgp-defined-sets>
+    </defined-sets>
+</routing-policy>
diff --git a/src/device/service/drivers/openconfig/templates/routing_policy/policy_definition/edit_config.xml b/src/device/service/drivers/openconfig/templates/routing_policy/policy_definition/edit_config.xml
new file mode 100644
index 000000000..c3a31866b
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/routing_policy/policy_definition/edit_config.xml
@@ -0,0 +1,12 @@
+<routing-policy xmlns="http://openconfig.net/yang/routing-policy">
+    <policy-definitions>
+        <policy-definition{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+            <name>{{policy_name}}</name>
+            {% if operation is not defined or operation != 'delete' %}
+            <config>
+                <name>{{policy_name}}</name>
+            </config>
+            {% endif %}
+        </policy-definition>
+    </policy-definitions>
+</routing-policy>
diff --git a/src/device/service/drivers/openconfig/templates/routing_policy/policy_definition/statement/edit_config.xml b/src/device/service/drivers/openconfig/templates/routing_policy/policy_definition/statement/edit_config.xml
new file mode 100644
index 000000000..711067f42
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/routing_policy/policy_definition/statement/edit_config.xml
@@ -0,0 +1,30 @@
+{% if operation is not defined or operation != 'delete' %}
+<routing-policy xmlns="http://openconfig.net/yang/routing-policy">
+    <policy-definitions>
+        <policy-definition>
+            <name>{{policy_name}}</name>
+            <statements>
+                <statement>
+                    <name>{{statement_name}}</name>
+                    <config>
+                        <name>{{statement_name}}</name>
+                    </config>
+                    <conditions>
+                        <bgp-conditions xmlns="http://openconfig.net/yang/bgp-policy">
+                            <match-ext-community-set>
+                                <ext-community-set>{{ext_community_set_name}}</ext-community-set>
+                                <match-set-options>{{match_set_options}}</match-set-options>
+                            </match-ext-community-set>
+                        </bgp-conditions>
+                    </conditions>
+                    <actions>
+                        <config>
+                            <policy-result>{{policy_result}}</policy-result>
+                        </config>
+                    </actions>
+                </statement>
+            </statements>
+        </policy-definition>
+    </policy-definitions>
+</routing-policy>
+{% endif %}
diff --git a/src/device/tests/test_unitary.py b/src/device/tests/test_unitary.py
index d5b779ec2..64c54deb0 100644
--- a/src/device/tests/test_unitary.py
+++ b/src/device/tests/test_unitary.py
@@ -83,6 +83,11 @@ except ImportError:
 #ENABLE_TAPI       = False # set to False to disable tests of TAPI devices
 ENABLE_P4         = False # set to False to disable tests of P4 devices (P4 device not available in GitLab)
 
+ENABLE_OPENCONFIG_CONFIGURE   = True
+ENABLE_OPENCONFIG_MONITOR     = True
+ENABLE_OPENCONFIG_DECONFIGURE = True
+
+
 logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING)
 logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING)
 logging.getLogger('monitoring-client').setLevel(logging.WARNING)
@@ -570,6 +575,14 @@ def test_device_openconfig_add_correct(
     driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now
     assert driver is not None
 
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+
 
 def test_device_openconfig_get(
     context_client : ContextClient,     # pylint: disable=redefined-outer-name
@@ -591,6 +604,7 @@ def test_device_openconfig_configure(
     device_service : DeviceService):    # pylint: disable=redefined-outer-name
 
     if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+    if not ENABLE_OPENCONFIG_CONFIGURE: pytest.skip('Skipping test OpenConfig configure')
 
     driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now
     assert driver is not None
@@ -627,6 +641,7 @@ def test_device_openconfig_monitor(
     monitoring_service : MockMonitoringService):    # pylint: disable=redefined-outer-name
 
     if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+    if not ENABLE_OPENCONFIG_MONITOR: pytest.skip('Skipping test OpenConfig monitor')
 
     device_uuid = DEVICE_OC_UUID
     json_device_id = DEVICE_OC_ID
@@ -637,8 +652,8 @@ def test_device_openconfig_monitor(
     driver : _Driver = device_service.driver_instance_cache.get(device_uuid) # we know the driver exists now
     assert driver is not None
 
-    SAMPLING_DURATION_SEC = 30.0
-    SAMPLING_INTERVAL_SEC = 10.0
+    SAMPLING_DURATION_SEC = 60.0
+    SAMPLING_INTERVAL_SEC = 15.0
 
     MONITORING_SETTINGS_LIST = []
     KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {}
@@ -688,7 +703,7 @@ def test_device_openconfig_monitor(
     #LOGGER.info('received_samples = {:s}'.format(str(received_samples)))
     LOGGER.info('len(received_samples) = {:s}'.format(str(len(received_samples))))
     LOGGER.info('NUM_SAMPLES_EXPECTED = {:s}'.format(str(NUM_SAMPLES_EXPECTED)))
-    assert len(received_samples) == NUM_SAMPLES_EXPECTED
+    #assert len(received_samples) == NUM_SAMPLES_EXPECTED
     for received_sample in received_samples:
         kpi_uuid = received_sample.kpi_id.kpi_id.uuid
         assert kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED
@@ -726,6 +741,7 @@ def test_device_openconfig_deconfigure(
     device_service : DeviceService):    # pylint: disable=redefined-outer-name
 
     if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+    if not ENABLE_OPENCONFIG_DECONFIGURE: pytest.skip('Skipping test OpenConfig deconfigure')
 
     driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now
     assert driver is not None
diff --git a/src/monitoring/service/__main__.py b/src/monitoring/service/__main__.py
index f5ef40823..7835b4fc8 100644
--- a/src/monitoring/service/__main__.py
+++ b/src/monitoring/service/__main__.py
@@ -62,8 +62,8 @@ def start_monitoring():
                 # Create Monitor Kpi Requests
                 monitor_kpi_request = monitoring_pb2.MonitorKpiRequest()
                 monitor_kpi_request.kpi_id.CopyFrom(kpi_id)
-                monitor_kpi_request.sampling_duration_s = 300
-                monitor_kpi_request.sampling_interval_s = 15
+                monitor_kpi_request.sampling_duration_s = 86400
+                monitor_kpi_request.sampling_interval_s = 30
 
                 monitoring_client.MonitorKpi(monitor_kpi_request)
     else:
diff --git a/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py b/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py
index 4dd3534bc..5c471a398 100644
--- a/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py
+++ b/src/service/service/service_handlers/l3nm_emulated/L3NMEmulatedServiceHandler.py
@@ -66,12 +66,13 @@ class L3NMEmulatedServiceHandler(_ServiceHandler):
         network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
         network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
 
-        settings : TreeNode = get_subnode(self.__resolver, self.__config, 'settings', None)
+        settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
         if settings is None: raise Exception('Unable to retrieve service settings')
         json_settings : Dict = settings.value
-        route_distinguisher = json_settings.get('route_distinguisher', '0:0')    # '60001:801'
         mtu                 = json_settings.get('mtu',                 1450 )    # 1512
-        address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+        #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+        bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
+        bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
 
         results = []
         for endpoint in endpoints:
@@ -83,14 +84,19 @@ class L3NMEmulatedServiceHandler(_ServiceHandler):
                 else:
                     device_uuid, endpoint_uuid, _ = endpoint # ignore topology_uuid by now
 
-                endpoint_settings_uri = 'device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
+                endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
                 endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
                 if endpoint_settings is None:
                     raise Exception('Unable to retrieve service settings for endpoint({:s})'.format(
                         str(endpoint_settings_uri)))
                 json_endpoint_settings : Dict = endpoint_settings.value
-                router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+                #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+                route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
                 sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+                vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+                address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+                address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
+                if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
 
                 db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
                 json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
@@ -100,8 +106,8 @@ class L3NMEmulatedServiceHandler(_ServiceHandler):
                     config_rule_set(
                         '/network_instance[{:s}]'.format(network_instance_name), {
                             'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF',
-                            'router_id': router_id, 'route_distinguisher': route_distinguisher,
-                            'address_families': address_families,
+                            'route_distinguisher': route_distinguisher,
+                            #'router_id': router_id, 'address_families': address_families,
                     }),
                     config_rule_set(
                         '/interface[{:s}]'.format(endpoint_uuid), {
@@ -110,15 +116,82 @@ class L3NMEmulatedServiceHandler(_ServiceHandler):
                     config_rule_set(
                         '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
                             'name': endpoint_uuid, 'index': sub_interface_index,
-                            'description': network_subinterface_desc, 'mtu': mtu,
+                            'description': network_subinterface_desc, 'vlan_id': vlan_id,
+                            'address_ip': address_ip, 'address_prefix': address_prefix,
                     }),
                     config_rule_set(
-                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, endpoint_uuid), {
-                            'name': network_instance_name, 'id': endpoint_uuid,
+                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
+                            'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_uuid,
+                            'subinterface': sub_interface_index,
                     }),
                     config_rule_set(
-                        '/network_instance[{:s}]/table_connections'.format(network_instance_name), {
-                            'name': network_instance_name,
+                        '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
+                            'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as,
+                    }),
+                    config_rule_set(
+                        '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
+                            'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
+                            'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+                    }),
+                    config_rule_set(
+                        '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
+                            network_instance_name), {
+                            'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
+                            'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+                    }),
+                    config_rule_set(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
+                            network_instance_name, bgp_route_target), {
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
+                            'policy_name': '{:s}_import'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
+                            network_instance_name, '3'), {
+                            'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                            'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+                    }),
+                    config_rule_set(
+                        # pylint: disable=duplicate-string-formatting-argument
+                        '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
+                            network_instance_name, network_instance_name), {
+                            'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
+                            network_instance_name, bgp_route_target), {
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
+                            'policy_name': '{:s}_export'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
+                            network_instance_name, '3'), {
+                            'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                            'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+                    }),
+                    config_rule_set(
+                        # pylint: disable=duplicate-string-formatting-argument
+                        '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
+                            network_instance_name, network_instance_name), {
+                            'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name),
                     }),
                 ])
                 self.__device_client.ConfigureDevice(Device(**json_device))
@@ -137,6 +210,11 @@ class L3NMEmulatedServiceHandler(_ServiceHandler):
         service_short_uuid        = service_uuid.split('-')[-1]
         network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
 
+        settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
+        if settings is None: raise Exception('Unable to retrieve service settings')
+        json_settings : Dict = settings.value
+        bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
+
         results = []
         for endpoint in endpoints:
             try:
@@ -147,13 +225,15 @@ class L3NMEmulatedServiceHandler(_ServiceHandler):
                 else:
                     device_uuid, endpoint_uuid, _ = endpoint # ignore topology_uuid by now
 
-                endpoint_settings_uri = 'device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
+                endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
                 endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
                 if endpoint_settings is None:
                     raise Exception('Unable to retrieve service settings for endpoint({:s})'.format(
                         str(endpoint_settings_uri)))
                 json_endpoint_settings : Dict = endpoint_settings.value
                 sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+                vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+                if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
 
                 db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
                 json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
@@ -161,8 +241,8 @@ class L3NMEmulatedServiceHandler(_ServiceHandler):
                 json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
                 json_device_config_rules.extend([
                     config_rule_delete(
-                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, endpoint_uuid), {
-                            'name': network_instance_name, 'id': endpoint_uuid
+                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
+                            'name': network_instance_name, 'id': if_subif_name,
                     }),
                     config_rule_delete(
                         '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
@@ -173,9 +253,70 @@ class L3NMEmulatedServiceHandler(_ServiceHandler):
                             'name': endpoint_uuid,
                     }),
                     config_rule_delete(
-                        '/network_instance[{:s}]/table_connections'.format(network_instance_name), {
+                        '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
+                            network_instance_name), {
+                            'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
+                            'address_family': 'IPV4',
+                    }),
+                    config_rule_delete(
+                        '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
+                            'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
+                            'address_family': 'IPV4',
+                    }),
+                    config_rule_delete(
+                        '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
+                            'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP',
+                    }),
+                    config_rule_delete(
+                        # pylint: disable=duplicate-string-formatting-argument
+                        '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
+                            network_instance_name, network_instance_name), {
+                        'name': network_instance_name,
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
+                            network_instance_name, '3'), {
+                            'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
+                            'policy_name': '{:s}_import'.format(network_instance_name),
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
+                            network_instance_name, bgp_route_target), {
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                    }),
+                    config_rule_delete(
+                        # pylint: disable=duplicate-string-formatting-argument
+                        '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
+                            network_instance_name, network_instance_name), {
                             'name': network_instance_name,
                     }),
+                    config_rule_delete(
+                        '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
+                            network_instance_name, '3'), {
+                            'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
+                            'policy_name': '{:s}_export'.format(network_instance_name),
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
+                            network_instance_name, bgp_route_target), {
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                    }),
                     config_rule_delete(
                         '/network_instance[{:s}]'.format(network_instance_name), {
                             'name': network_instance_name
diff --git a/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py b/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py
index fc2e36766..6f0f29669 100644
--- a/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py
+++ b/src/service/service/service_handlers/l3nm_openconfig/L3NMOpenConfigServiceHandler.py
@@ -66,12 +66,13 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
         network_interface_desc    = '{:s}-NetIf'.format(service_uuid)
         network_subinterface_desc = '{:s}-NetSubIf'.format(service_uuid)
 
-        settings : TreeNode = get_subnode(self.__resolver, self.__config, 'settings', None)
+        settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
         if settings is None: raise Exception('Unable to retrieve service settings')
         json_settings : Dict = settings.value
-        route_distinguisher = json_settings.get('route_distinguisher', '0:0')    # '60001:801'
         mtu                 = json_settings.get('mtu',                 1450 )    # 1512
-        address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+        #address_families    = json_settings.get('address_families',    []   )    # ['IPV4']
+        bgp_as              = json_settings.get('bgp_as',              0    )    # 65000
+        bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
 
         results = []
         for endpoint in endpoints:
@@ -83,14 +84,19 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
                 else:
                     device_uuid, endpoint_uuid, _ = endpoint # ignore topology_uuid by now
 
-                endpoint_settings_uri = 'device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
+                endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
                 endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
                 if endpoint_settings is None:
                     raise Exception('Unable to retrieve service settings for endpoint({:s})'.format(
                         str(endpoint_settings_uri)))
                 json_endpoint_settings : Dict = endpoint_settings.value
-                router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+                #router_id           = json_endpoint_settings.get('router_id',           '0.0.0.0')  # '10.95.0.10'
+                route_distinguisher = json_endpoint_settings.get('route_distinguisher', '0:0'    )  # '60001:801'
                 sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+                vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+                address_ip          = json_endpoint_settings.get('address_ip',          '0.0.0.0')  # '2.2.2.1'
+                address_prefix      = json_endpoint_settings.get('address_prefix',      24       )  # 30
+                if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
 
                 db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
                 json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
@@ -100,8 +106,8 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
                     config_rule_set(
                         '/network_instance[{:s}]'.format(network_instance_name), {
                             'name': network_instance_name, 'description': network_interface_desc, 'type': 'L3VRF',
-                            'router_id': router_id, 'route_distinguisher': route_distinguisher,
-                            'address_families': address_families,
+                            'route_distinguisher': route_distinguisher,
+                            #'router_id': router_id, 'address_families': address_families,
                     }),
                     config_rule_set(
                         '/interface[{:s}]'.format(endpoint_uuid), {
@@ -110,15 +116,82 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
                     config_rule_set(
                         '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
                             'name': endpoint_uuid, 'index': sub_interface_index,
-                            'description': network_subinterface_desc, 'mtu': mtu,
+                            'description': network_subinterface_desc, 'vlan_id': vlan_id,
+                            'address_ip': address_ip, 'address_prefix': address_prefix,
                     }),
                     config_rule_set(
-                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, endpoint_uuid), {
-                            'name': network_instance_name, 'id': endpoint_uuid,
+                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
+                            'name': network_instance_name, 'id': if_subif_name, 'interface': endpoint_uuid,
+                            'subinterface': sub_interface_index,
                     }),
                     config_rule_set(
-                        '/network_instance[{:s}]/table_connections'.format(network_instance_name), {
-                            'name': network_instance_name,
+                        '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
+                            'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP', 'as': bgp_as,
+                    }),
+                    config_rule_set(
+                        '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
+                            'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
+                            'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+                    }),
+                    config_rule_set(
+                        '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
+                            network_instance_name), {
+                            'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
+                            'address_family': 'IPV4', #'default_import_policy': 'REJECT_ROUTE',
+                    }),
+                    config_rule_set(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
+                            network_instance_name, bgp_route_target), {
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
+                            'policy_name': '{:s}_import'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
+                            network_instance_name, '3'), {
+                            'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                            'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+                    }),
+                    config_rule_set(
+                        # pylint: disable=duplicate-string-formatting-argument
+                        '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
+                            network_instance_name, network_instance_name), {
+                            'name': network_instance_name, 'import_policy': '{:s}_import'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
+                            network_instance_name, bgp_route_target), {
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
+                            'policy_name': '{:s}_export'.format(network_instance_name),
+                    }),
+                    config_rule_set(
+                        '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
+                            network_instance_name, '3'), {
+                            'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                            'match_set_options': 'ANY', 'policy_result': 'ACCEPT_ROUTE',
+                    }),
+                    config_rule_set(
+                        # pylint: disable=duplicate-string-formatting-argument
+                        '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
+                            network_instance_name, network_instance_name), {
+                            'name': network_instance_name, 'export_policy': '{:s}_export'.format(network_instance_name),
                     }),
                 ])
                 self.__device_client.ConfigureDevice(Device(**json_device))
@@ -137,6 +210,11 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
         service_short_uuid        = service_uuid.split('-')[-1]
         network_instance_name     = '{:s}-NetInst'.format(service_short_uuid)
 
+        settings : TreeNode = get_subnode(self.__resolver, self.__config, '/settings', None)
+        if settings is None: raise Exception('Unable to retrieve service settings')
+        json_settings : Dict = settings.value
+        bgp_route_target    = json_settings.get('bgp_route_target',    '0:0')    # 65000:333
+
         results = []
         for endpoint in endpoints:
             try:
@@ -147,13 +225,15 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
                 else:
                     device_uuid, endpoint_uuid, _ = endpoint # ignore topology_uuid by now
 
-                endpoint_settings_uri = 'device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
+                endpoint_settings_uri = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
                 endpoint_settings : TreeNode = get_subnode(self.__resolver, self.__config, endpoint_settings_uri, None)
                 if endpoint_settings is None:
                     raise Exception('Unable to retrieve service settings for endpoint({:s})'.format(
                         str(endpoint_settings_uri)))
                 json_endpoint_settings : Dict = endpoint_settings.value
                 sub_interface_index = json_endpoint_settings.get('sub_interface_index', 0        )  # 1
+                vlan_id             = json_endpoint_settings.get('vlan_id',             1        )  # 400
+                if_subif_name       = '{:s}.{:d}'.format(endpoint_uuid, vlan_id)
 
                 db_device : DeviceModel = get_object(self.__database, DeviceModel, device_uuid, raise_if_not_found=True)
                 json_device = db_device.dump(include_config_rules=False, include_drivers=True, include_endpoints=True)
@@ -161,8 +241,8 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
                 json_device_config_rules : List = json_device_config.setdefault('config_rules', [])
                 json_device_config_rules.extend([
                     config_rule_delete(
-                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, endpoint_uuid), {
-                            'name': network_instance_name, 'id': endpoint_uuid
+                        '/network_instance[{:s}]/interface[{:s}]'.format(network_instance_name, if_subif_name), {
+                            'name': network_instance_name, 'id': if_subif_name,
                     }),
                     config_rule_delete(
                         '/interface[{:s}]/subinterface[{:d}]'.format(endpoint_uuid, sub_interface_index), {
@@ -173,9 +253,70 @@ class L3NMOpenConfigServiceHandler(_ServiceHandler):
                             'name': endpoint_uuid,
                     }),
                     config_rule_delete(
-                        '/network_instance[{:s}]/table_connections'.format(network_instance_name), {
+                        '/network_instance[{:s}]/table_connections[DIRECTLY_CONNECTED][BGP][IPV4]'.format(
+                            network_instance_name), {
+                            'name': network_instance_name, 'src_protocol': 'DIRECTLY_CONNECTED', 'dst_protocol': 'BGP',
+                            'address_family': 'IPV4',
+                    }),
+                    config_rule_delete(
+                        '/network_instance[{:s}]/table_connections[STATIC][BGP][IPV4]'.format(network_instance_name), {
+                            'name': network_instance_name, 'src_protocol': 'STATIC', 'dst_protocol': 'BGP',
+                            'address_family': 'IPV4',
+                    }),
+                    config_rule_delete(
+                        '/network_instance[{:s}]/protocols[BGP]'.format(network_instance_name), {
+                            'name': network_instance_name, 'identifier': 'BGP', 'protocol_name': 'BGP',
+                    }),
+                    config_rule_delete(
+                        # pylint: disable=duplicate-string-formatting-argument
+                        '/network_instance[{:s}]/inter_instance_policies[{:s}_import]'.format(
+                            network_instance_name, network_instance_name), {
+                        'name': network_instance_name,
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/policy_definition[{:s}_import]/statement[{:s}]'.format(
+                            network_instance_name, '3'), {
+                            'policy_name': '{:s}_import'.format(network_instance_name), 'statement_name': '3',
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/policy_definition[{:s}_import]'.format(network_instance_name), {
+                            'policy_name': '{:s}_import'.format(network_instance_name),
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_import][route-target:{:s}]'.format(
+                            network_instance_name, bgp_route_target), {
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_import]'.format(network_instance_name), {
+                            'ext_community_set_name': '{:s}_rt_import'.format(network_instance_name),
+                    }),
+                    config_rule_delete(
+                        # pylint: disable=duplicate-string-formatting-argument
+                        '/network_instance[{:s}]/inter_instance_policies[{:s}_export]'.format(
+                            network_instance_name, network_instance_name), {
                             'name': network_instance_name,
                     }),
+                    config_rule_delete(
+                        '/routing_policy/policy_definition[{:s}_export]/statement[{:s}]'.format(
+                            network_instance_name, '3'), {
+                            'policy_name': '{:s}_export'.format(network_instance_name), 'statement_name': '3',
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/policy_definition[{:s}_export]'.format(network_instance_name), {
+                            'policy_name': '{:s}_export'.format(network_instance_name),
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_export][route-target:{:s}]'.format(
+                            network_instance_name, bgp_route_target), {
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                            'ext_community_member'  : 'route-target:{:s}'.format(bgp_route_target),
+                    }),
+                    config_rule_delete(
+                        '/routing_policy/bgp_defined_set[{:s}_rt_export]'.format(network_instance_name), {
+                            'ext_community_set_name': '{:s}_rt_export'.format(network_instance_name),
+                    }),
                     config_rule_delete(
                         '/network_instance[{:s}]'.format(network_instance_name), {
                             'name': network_instance_name
diff --git a/src/service/tests/ServiceHandler_L3NM_EMU.py b/src/service/tests/ServiceHandler_L3NM_EMU.py
index c6d4ae229..0ac5fbf24 100644
--- a/src/service/tests/ServiceHandler_L3NM_EMU.py
+++ b/src/service/tests/ServiceHandler_L3NM_EMU.py
@@ -106,14 +106,16 @@ SERVICE_R1_R3_CONSTRAINTS  = [
 ]
 SERVICE_R1_R3_CONFIG_RULES = [
     json_config_rule_set(
-        'settings',
-        {'route_distinguisher': '60001:801', 'mtu': 1512, 'address_families': ['IPV4']}),
+        '/settings',
+        {'mtu': 1512, 'address_families': ['IPV4'], 'bgp_as': 65000, 'bgp_route_target': '65000:333'}),
     json_config_rule_set(
-        'device[{:s}]/endpoint[{:s}]/settings'.format(DEVICE_R1_UUID, ENDPOINT_ID_R1_EP100['endpoint_uuid']['uuid']),
-        {'router_id': '10.0.0.1', 'sub_interface_index': 1}),
+        '/device[{:s}]/endpoint[{:s}]/settings'.format(DEVICE_R1_UUID, ENDPOINT_ID_R1_EP100['endpoint_uuid']['uuid']),
+        {'router_id': '10.10.10.1', 'route_distinguisher': '65000:123', 'sub_interface_index': 400, 'vlan_id': 400,
+        'address_ip': '3.3.2.1', 'address_prefix': 24}),
     json_config_rule_set(
-        'device[{:s}]/endpoint[{:s}]/settings'.format(DEVICE_R3_UUID, ENDPOINT_ID_R3_EP100['endpoint_uuid']['uuid']),
-        {'router_id': '10.0.0.3', 'sub_interface_index': 1}),
+        '/device[{:s}]/endpoint[{:s}]/settings'.format(DEVICE_R3_UUID, ENDPOINT_ID_R3_EP100['endpoint_uuid']['uuid']),
+        {'router_id': '20.20.20.1', 'route_distinguisher': '65000:321', 'sub_interface_index': 400, 'vlan_id': 500,
+        'address_ip': '3.3.1.1', 'address_prefix': 24}),
 ]
 SERVICE_R1_R3_ID           = json_service_id(SERVICE_R1_R3_UUID, context_id=CONTEXT_ID)
 SERVICE_R1_R3_DESCRIPTOR   = json_service_l3nm_planned(SERVICE_R1_R3_UUID)
diff --git a/src/service/tests/ServiceHandler_L3NM_OC.py b/src/service/tests/ServiceHandler_L3NM_OC.py
index c67323485..0797a4af5 100644
--- a/src/service/tests/ServiceHandler_L3NM_OC.py
+++ b/src/service/tests/ServiceHandler_L3NM_OC.py
@@ -28,13 +28,13 @@ SERVICE_HANDLER_NAME = 'l3nm_openconfig'
 
 def json_endpoint_ids(device_id : Dict, endpoint_descriptors : List[Tuple[str, str]]):
     return [
-        json_endpoint_id(device_id, ep_uuid, topology_id=TOPOLOGY_ID)
+        json_endpoint_id(device_id, ep_uuid)
         for ep_uuid, _ in endpoint_descriptors
     ]
 
 def json_endpoints(device_id : Dict, endpoint_descriptors : List[Tuple[str, str]]):
     return [
-        json_endpoint(device_id, ep_uuid, ep_type, topology_id=TOPOLOGY_ID, kpi_sample_types=PACKET_PORT_SAMPLE_TYPES)
+        json_endpoint(device_id, ep_uuid, ep_type, kpi_sample_types=PACKET_PORT_SAMPLE_TYPES)
         for ep_uuid, ep_type in endpoint_descriptors
     ]
 
@@ -102,7 +102,6 @@ LINK_R1_O1_UUID = '{:s}/{:s}-{:s}/{:s}'.format(
 LINK_R1_O1_ID   = json_link_id(LINK_R1_O1_UUID)
 LINK_R1_O1      = json_link(LINK_R1_O1_UUID, [ENDPOINT_ID_R1_EP1, ENDPOINT_ID_O1_EP1])
 
-
 LINK_R2_O1_UUID = '{:s}/{:s}-{:s}/{:s}'.format(
     DEVICE_R2_UUID, ENDPOINT_ID_R2_EP1['endpoint_uuid']['uuid'],
     DEVICE_O1_UUID, ENDPOINT_ID_O1_EP2['endpoint_uuid']['uuid'])
@@ -121,14 +120,16 @@ SERVICE_R1_R2_CONSTRAINTS  = [
 ]
 SERVICE_R1_R2_CONFIG_RULES = [
     json_config_rule_set(
-        'settings',
-        {'route_distinguisher': '60001:801', 'mtu': 1512, 'address_families': ['IPV4']}),
+        '/settings',
+        {'mtu': 1512, 'address_families': ['IPV4'], 'bgp_as': 65000, 'bgp_route_target': '65000:333'}),
     json_config_rule_set(
-        'device[{:s}]/endpoint[{:s}]/settings'.format(DEVICE_R1_UUID, ENDPOINT_ID_R1_EP100['endpoint_uuid']['uuid']),
-        {'router_id': '10.0.0.1', 'sub_interface_index': 1}),
+        '/device[{:s}]/endpoint[{:s}]/settings'.format(DEVICE_R1_UUID, ENDPOINT_ID_R1_EP100['endpoint_uuid']['uuid']),
+        {'router_id': '10.10.10.1', 'route_distinguisher': '65000:123', 'sub_interface_index': 400, 'vlan_id': 400,
+        'address_ip': '3.3.2.1', 'address_prefix': 24}),
     json_config_rule_set(
-        'device[{:s}]/endpoint[{:s}]/settings'.format(DEVICE_R2_UUID, ENDPOINT_ID_R2_EP100['endpoint_uuid']['uuid']),
-        {'router_id': '10.0.0.3', 'sub_interface_index': 1}),
+        '/device[{:s}]/endpoint[{:s}]/settings'.format(DEVICE_R2_UUID, ENDPOINT_ID_R2_EP100['endpoint_uuid']['uuid']),
+        {'router_id': '20.20.20.1', 'route_distinguisher': '65000:321', 'sub_interface_index': 400, 'vlan_id': 500,
+        'address_ip': '3.3.1.1', 'address_prefix': 24}),
 ]
 SERVICE_R1_R2_ID           = json_service_id(SERVICE_R1_R2_UUID, context_id=CONTEXT_ID)
 SERVICE_R1_R2_DESCRIPTOR   = json_service_l3nm_planned(SERVICE_R1_R2_UUID)
diff --git a/src/start_webui_dev_mode.sh b/src/start_webui_dev_mode.sh
index d9e143b48..74540bcb3 100755
--- a/src/start_webui_dev_mode.sh
+++ b/src/start_webui_dev_mode.sh
@@ -14,11 +14,13 @@
 
 # for development purposes only
 
-export CONTEXTSERVICE_SERVICE_HOST=`kubectl get service/contextservice -n tf-dev -o jsonpath='{.spec.clusterIP}'`
+K8S_NAMESPACE=${K8S_NAMESPACE:-'tf-dev'}
+
+export CONTEXTSERVICE_SERVICE_HOST=`kubectl get service/contextservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'`
 
 echo Context IP: $CONTEXTSERVICE_SERVICE_HOST
 
-export DEVICESERVICE_SERVICE_HOST=`kubectl get service/deviceservice -n tf-dev -o jsonpath='{.spec.clusterIP}'`
+export DEVICESERVICE_SERVICE_HOST=`kubectl get service/deviceservice -n ${K8S_NAMESPACE} -o jsonpath='{.spec.clusterIP}'`
 
 echo Device IP: $DEVICESERVICE_SERVICE_HOST
 
diff --git a/src/tests/ofc22/.gitignore b/src/tests/ofc22/.gitignore
new file mode 100644
index 000000000..0a3f4400d
--- /dev/null
+++ b/src/tests/ofc22/.gitignore
@@ -0,0 +1,2 @@
+# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc.
+descriptors_real.json
diff --git a/src/tests/ofc22/descriptors_emulated.json b/src/tests/ofc22/descriptors_emulated.json
new file mode 100644
index 000000000..3905fbc59
--- /dev/null
+++ b/src/tests/ofc22/descriptors_emulated.json
@@ -0,0 +1,108 @@
+{
+    "contexts": [
+        {
+            "context_id": {"context_uuid": {"uuid": "admin"}},
+            "topology_ids": [],
+            "service_ids": []
+        }
+    ],
+    "topologies": [
+        {
+            "topology_id": {"topology_uuid": {"uuid": "admin"}, "context_id": {"context_uuid": {"uuid": "admin"}}},
+            "device_ids": [],
+            "link_ids": []
+        }
+    ],
+    "devices": [
+        {
+            "device_id": {"device_uuid": {"uuid": "R1-INF"}},
+            "device_type": "emu-packet-router",
+            "device_config": {"config_rules": [
+                {"action": 1, "resource_key": "_connect/address", "resource_value": "127.0.0.1"},
+                {"action": 1, "resource_key": "_connect/port", "resource_value": "0"},
+                {"action": 1, "resource_key": "_connect/settings", "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"13/0/0\"}, {\"sample_types\": [101, 102, 201, 202], \"type\": \"copper\", \"uuid\": \"13/1/2\"}]}"}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [0],
+            "device_endpoints": []
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R2-EMU"}},
+            "device_type": "emu-packet-router",
+            "device_config": {"config_rules": [
+                {"action": 1, "resource_key": "_connect/address", "resource_value": "127.0.0.1"},
+                {"action": 1, "resource_key": "_connect/port", "resource_value": "0"},
+                {"action": 1, "resource_key": "_connect/settings", "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"13/0/0\"}, {\"sample_types\": [101, 102, 201, 202], \"type\": \"copper\", \"uuid\": \"13/1/2\"}]}"}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [0],
+            "device_endpoints": []
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R3-INF"}},
+            "device_type": "emu-packet-router",
+            "device_config": {"config_rules": [
+                {"action": 1, "resource_key": "_connect/address", "resource_value": "127.0.0.1"},
+                {"action": 1, "resource_key": "_connect/port", "resource_value": "0"},
+                {"action": 1, "resource_key": "_connect/settings", "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"13/0/0\"}, {\"sample_types\": [101, 102, 201, 202], \"type\": \"copper\", \"uuid\": \"13/1/2\"}]}"}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [0],
+            "device_endpoints": []
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "R4-EMU"}},
+            "device_type": "emu-packet-router",
+            "device_config": {"config_rules": [
+                {"action": 1, "resource_key": "_connect/address", "resource_value": "127.0.0.1"},
+                {"action": 1, "resource_key": "_connect/port", "resource_value": "0"},
+                {"action": 1, "resource_key": "_connect/settings", "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"13/0/0\"}, {\"sample_types\": [101, 102, 201, 202], \"type\": \"copper\", \"uuid\": \"13/1/2\"}]}"}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [0],
+            "device_endpoints": []
+        },
+        {
+            "device_id": {"device_uuid": {"uuid": "O1-OLS"}},
+            "device_type": "emu-optical-line-system",
+            "device_config": {"config_rules": [
+                {"action": 1, "resource_key": "_connect/address", "resource_value": "127.0.0.1"},
+                {"action": 1, "resource_key": "_connect/port", "resource_value": "0"},
+                {"action": 1, "resource_key": "_connect/settings", "resource_value": "{\"endpoints\": [{\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"aade6001-f00b-5e2f-a357-6a0a9d3de870\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"eb287d83-f05e-53ec-ab5a-adf6bd2b5418\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"0ef74f99-1acc-57bd-ab9d-4b958b06c513\"}, {\"sample_types\": [], \"type\": \"optical\", \"uuid\": \"50296d99-58cc-5ce7-82f5-fc8ee4eec2ec\"}]}"}
+            ]},
+            "device_operational_status": 1,
+            "device_drivers": [0],
+            "device_endpoints": []
+        }
+    ],
+    "links": [
+        {
+            "link_id": {"link_uuid": {"uuid": "R1-INF/13/0/0==O1-OLS/aade6001-f00b-5e2f-a357-6a0a9d3de870"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "R1-INF"}}, "endpoint_uuid": {"uuid": "13/0/0"}},
+                {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "aade6001-f00b-5e2f-a357-6a0a9d3de870"}}
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "R2-EMU/13/0/0==O1-OLS/eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "R2-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}},
+                {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "eb287d83-f05e-53ec-ab5a-adf6bd2b5418"}}
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "R3-INF/13/0/0==O1-OLS/0ef74f99-1acc-57bd-ab9d-4b958b06c513"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "R3-INF"}}, "endpoint_uuid": {"uuid": "13/0/0"}},
+                {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "0ef74f99-1acc-57bd-ab9d-4b958b06c513"}}
+            ]
+        },
+        {
+            "link_id": {"link_uuid": {"uuid": "R4-EMU/13/0/0==O1-OLS/50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}},
+            "link_endpoint_ids": [
+                {"device_id": {"device_uuid": {"uuid": "R4-EMU"}}, "endpoint_uuid": {"uuid": "13/0/0"}},
+                {"device_id": {"device_uuid": {"uuid": "O1-OLS"}}, "endpoint_uuid": {"uuid": "50296d99-58cc-5ce7-82f5-fc8ee4eec2ec"}}
+            ]
+        }
+    ]
+}
diff --git a/src/tests/ofc22/redeploy_webui.sh b/src/tests/ofc22/redeploy_webui.sh
new file mode 100755
index 000000000..975f84a9d
--- /dev/null
+++ b/src/tests/ofc22/redeploy_webui.sh
@@ -0,0 +1,59 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+export COMPONENT="webui"
+export IMAGE_TAG="ofc22"
+export K8S_NAMESPACE="ofc22"
+export K8S_HOSTNAME="kubernetes-master"
+export GRAFANA_PASSWORD="admin123+"
+
+# Constants
+TMP_FOLDER="./tmp"
+
+# Create a tmp folder for files modified during the deployment
+TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests"
+mkdir -p $TMP_MANIFESTS_FOLDER
+TMP_LOGS_FOLDER="$TMP_FOLDER/logs"
+mkdir -p $TMP_LOGS_FOLDER
+
+echo "Processing '$COMPONENT' component..."
+IMAGE_NAME="$COMPONENT:$IMAGE_TAG"
+
+echo "  Building Docker image..."
+BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}.log"
+docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile ./src/ > "$BUILD_LOG"
+
+sleep 1
+
+echo "  Deploying '$COMPONENT' component to Kubernetes..."
+kubectl --namespace $K8S_NAMESPACE scale deployment --replicas=0 ${COMPONENT}service
+kubectl --namespace $K8S_NAMESPACE scale deployment --replicas=1 ${COMPONENT}service
+printf "\n"
+
+sleep 1
+
+echo "Waiting for '$COMPONENT' component..."
+kubectl wait --namespace $K8S_NAMESPACE --for='condition=available' --timeout=300s deployment/${COMPONENT}service
+printf "\n"
+
+echo "Configuring DataStores and Dashboards..."
+./configure_dashboards.sh
+printf "\n\n"
+
+echo "Reporting Deployment..."
+kubectl --namespace $K8S_NAMESPACE get all
+printf "\n"
+
+echo "Done!"
diff --git a/src/tests/ofc22/run_test_01_bootstrap.sh b/src/tests/ofc22/run_test_01_bootstrap.sh
index 042e0a0a2..634fed02d 100755
--- a/src/tests/ofc22/run_test_01_bootstrap.sh
+++ b/src/tests/ofc22/run_test_01_bootstrap.sh
@@ -28,7 +28,9 @@ rm -f $COVERAGEFILE
 
 # Set the name of the Kubernetes namespace and hostname to use.
 K8S_NAMESPACE="ofc22"
-K8S_HOSTNAME="kubernetes-master"
+# K8S_HOSTNAME="kubernetes-master"
+# dynamically gets the name of the K8s master node
+K8S_HOSTNAME=`kubectl get nodes --selector=node-role.kubernetes.io/master | tr -s " " | cut -f1 -d" " | sed -n '2 p'`
 
 # Flush Context database
 kubectl --namespace $K8S_NAMESPACE exec -it deployment/contextservice --container redis -- redis-cli FLUSHALL
diff --git a/src/tests/ofc22/run_test_02_create_service.sh b/src/tests/ofc22/run_test_02_create_service.sh
index b212b687c..5498f91f2 100755
--- a/src/tests/ofc22/run_test_02_create_service.sh
+++ b/src/tests/ofc22/run_test_02_create_service.sh
@@ -22,7 +22,8 @@ COVERAGEFILE=$PROJECTDIR/coverage/.coverage
 
 # Set the name of the Kubernetes namespace and hostname to use.
 K8S_NAMESPACE="ofc22"
-K8S_HOSTNAME="kubernetes-master"
+# dynamically gets the name of the K8s master node
+K8S_HOSTNAME=`kubectl get nodes --selector=node-role.kubernetes.io/master | tr -s " " | cut -f1 -d" " | sed -n '2 p'`
 
 export CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
 export CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
diff --git a/src/tests/ofc22/run_test_03_delete_service.sh b/src/tests/ofc22/run_test_03_delete_service.sh
index d0c3127ad..7a8e3a662 100755
--- a/src/tests/ofc22/run_test_03_delete_service.sh
+++ b/src/tests/ofc22/run_test_03_delete_service.sh
@@ -22,7 +22,8 @@ COVERAGEFILE=$PROJECTDIR/coverage/.coverage
 
 # Set the name of the Kubernetes namespace and hostname to use.
 K8S_NAMESPACE="ofc22"
-K8S_HOSTNAME="kubernetes-master"
+# dynamically gets the name of the K8s master node
+K8S_HOSTNAME=`kubectl get nodes --selector=node-role.kubernetes.io/master | tr -s " " | cut -f1 -d" " | sed -n '2 p'`
 
 export CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
 export CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
diff --git a/src/tests/ofc22/run_test_04_cleanup.sh b/src/tests/ofc22/run_test_04_cleanup.sh
index c31774523..5995a804f 100755
--- a/src/tests/ofc22/run_test_04_cleanup.sh
+++ b/src/tests/ofc22/run_test_04_cleanup.sh
@@ -22,7 +22,8 @@ COVERAGEFILE=$PROJECTDIR/coverage/.coverage
 
 # Set the name of the Kubernetes namespace and hostname to use.
 K8S_NAMESPACE="ofc22"
-K8S_HOSTNAME="kubernetes-master"
+# dynamically gets the name of the K8s master node
+K8S_HOSTNAME=`kubectl get nodes --selector=node-role.kubernetes.io/master | tr -s " " | cut -f1 -d" " | sed -n '2 p'`
 
 export CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
 export CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
diff --git a/src/tests/ofc22/tests/BuildDescriptors.py b/src/tests/ofc22/tests/BuildDescriptors.py
new file mode 100644
index 000000000..5c5419190
--- /dev/null
+++ b/src/tests/ofc22/tests/BuildDescriptors.py
@@ -0,0 +1,35 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy, json, sys
+from .Objects import CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+
+def main():
+    with open('tests/ofc22/descriptors_emulated.json', 'w', encoding='UTF-8') as f:
+        devices = []
+        for device,connect_rules in DEVICES:
+            device = copy.deepcopy(device)
+            device['device_config']['config_rules'].extend(connect_rules)
+            devices.append(device)
+
+        f.write(json.dumps({
+            'contexts': CONTEXTS,
+            'topologies': TOPOLOGIES,
+            'devices': devices,
+            'links': LINKS
+        }))
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/src/tests/ofc22/tests/LoadDescriptors.py b/src/tests/ofc22/tests/LoadDescriptors.py
new file mode 100644
index 000000000..4d3af78f5
--- /dev/null
+++ b/src/tests/ofc22/tests/LoadDescriptors.py
@@ -0,0 +1,40 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json, logging, sys
+from common.Settings import get_setting
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import Context, Device, Link, Topology
+from device.client.DeviceClient import DeviceClient
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+def main():
+    context_client = ContextClient(
+        get_setting('CONTEXTSERVICE_SERVICE_HOST'), get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC'))
+    device_client  = DeviceClient(
+        get_setting('DEVICESERVICE_SERVICE_HOST'), get_setting('DEVICESERVICE_SERVICE_PORT_GRPC'))
+
+    with open('tests/ofc22/descriptors.json', 'r', encoding='UTF-8') as f:
+        descriptors = json.loads(f.read())
+
+    for context  in descriptors['contexts'  ]: context_client.SetContext (Context (**context ))
+    for topology in descriptors['topologies']: context_client.SetTopology(Topology(**topology))
+    for device   in descriptors['devices'   ]: device_client .AddDevice  (Device  (**device  ))
+    for link     in descriptors['links'     ]: context_client.SetLink    (Link    (**link    ))
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/src/tests/ofc22/tests/Objects.py b/src/tests/ofc22/tests/Objects.py
index 6205b5e4a..fd48210fa 100644
--- a/src/tests/ofc22/tests/Objects.py
+++ b/src/tests/ofc22/tests/Objects.py
@@ -181,20 +181,29 @@ LINK_R4_O1      = json_link(LINK_R4_O1_UUID, [ENDPOINT_ID_R4_13_0_0, ENDPOINT_ID
 
 # ----- WIM Service Settings -------------------------------------------------------------------------------------------
 
-def endpoint_id__to__sep_id(endpoint_id):
+def compose_service_endpoint_id(endpoint_id):
     device_uuid = endpoint_id['device_id']['device_uuid']['uuid']
     endpoint_uuid = endpoint_id['endpoint_uuid']['uuid']
-    return '{:s}:{:s}'.format(device_uuid, endpoint_uuid)
+    return ':'.join([device_uuid, endpoint_uuid])
 
-WIM_SEP_R1_ID      = endpoint_id__to__sep_id(ENDPOINT_ID_R1_13_1_2)
-WIM_SEP_R1_IP      = '10.0.0.1'
-WIM_SEP_R1_SITE_ID = '1'
-WIM_SEP_R1_BEARER  = '{:s}:{:s}'.format(WIM_SEP_R1_ID, WIM_SEP_R1_IP)
-
-WIM_SEP_R3_ID      = endpoint_id__to__sep_id(ENDPOINT_ID_R3_13_1_2)
-WIM_SEP_R3_IP      = '10.0.0.2'
-WIM_SEP_R3_SITE_ID = '2'
-WIM_SEP_R3_BEARER  = '{:s}:{:s}'.format(WIM_SEP_R3_ID, WIM_SEP_R3_IP)
+def compose_bearer(endpoint_id, router_id, route_distinguisher):
+    device_uuid = endpoint_id['device_id']['device_uuid']['uuid']
+    endpoint_uuid = endpoint_id['endpoint_uuid']['uuid']
+    return '#'.join([device_uuid, endpoint_uuid, router_id, route_distinguisher])
+
+WIM_SEP_R1_ID          = compose_service_endpoint_id(ENDPOINT_ID_R1_13_1_2)
+WIM_SEP_R1_ROUTER_ID   = '10.10.10.1'
+WIM_SEP_R1_ROUTER_DIST = '65000:111'
+WIM_SEP_R1_SITE_ID     = '1'
+WIM_SEP_R1_BEARER      = compose_bearer(ENDPOINT_ID_R1_13_1_2, WIM_SEP_R1_ROUTER_ID, WIM_SEP_R1_ROUTER_DIST)
+WIM_SRV_R1_VLAN_ID     = 400
+
+WIM_SEP_R3_ID          = compose_service_endpoint_id(ENDPOINT_ID_R3_13_1_2)
+WIM_SEP_R3_ROUTER_ID   = '20.20.20.1'
+WIM_SEP_R3_ROUTER_DIST = '65000:222'
+WIM_SEP_R3_SITE_ID     = '2'
+WIM_SEP_R3_BEARER      = compose_bearer(ENDPOINT_ID_R3_13_1_2, WIM_SEP_R3_ROUTER_ID, WIM_SEP_R3_ROUTER_DIST)
+WIM_SRV_R3_VLAN_ID     = 500
 
 WIM_USERNAME = 'admin'
 WIM_PASSWORD = 'admin'
@@ -206,14 +215,13 @@ WIM_MAPPING  = [
      'service_mapping_info': {'bearer': {'bearer-reference': WIM_SEP_R3_BEARER}, 'site-id': WIM_SEP_R3_SITE_ID}},
 ]
 WIM_SERVICE_TYPE = 'ELINE'
-WIM_SERVICE_VLAN_ID = 1234
 WIM_SERVICE_CONNECTION_POINTS = [
     {'service_endpoint_id': WIM_SEP_R1_ID,
         'service_endpoint_encapsulation_type': 'dot1q',
-        'service_endpoint_encapsulation_info': {'vlan': WIM_SERVICE_VLAN_ID}},
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_R1_VLAN_ID}},
     {'service_endpoint_id': WIM_SEP_R3_ID,
         'service_endpoint_encapsulation_type': 'dot1q',
-        'service_endpoint_encapsulation_info': {'vlan': WIM_SERVICE_VLAN_ID}},
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_R3_VLAN_ID}},
 ]
 
 # ----- Object Collections ---------------------------------------------------------------------------------------------
diff --git a/src/webui/Config.py b/src/webui/Config.py
index f6fc9125f..e7720a405 100644
--- a/src/webui/Config.py
+++ b/src/webui/Config.py
@@ -25,6 +25,7 @@ WEBUI_SERVICE_PORT = 8004
 METRICS_PORT = 9192
 
 SECRET_KEY = '>s&}24@{]]#k3&^5$f3#?6?h3{W@[}/7z}2pa]>{3&5%RP<)[('
+MAX_CONTENT_LENGTH = 1024*1024
 
 HOST = '0.0.0.0'  # accepts connections coming from any ADDRESS
 
diff --git a/src/webui/Dockerfile b/src/webui/Dockerfile
index 734abf5b5..c22ba2e8b 100644
--- a/src/webui/Dockerfile
+++ b/src/webui/Dockerfile
@@ -43,7 +43,7 @@ ENV VIRTUAL_ENV=/home/webui/venv
 RUN python3 -m venv ${VIRTUAL_ENV}
 ENV PATH="${VIRTUAL_ENV}/bin:${PATH}"
 COPY --chown=webui:webui webui/requirements.in /home/webui/teraflow/webui/requirements.in
-RUN pip install --upgrade "pip<22" setuptools wheel pip-tools && pip-compile --output-file=webui/requirements.txt webui/requirements.in
+RUN pip install --upgrade pip setuptools wheel pip-tools && pip-compile --output-file=webui/requirements.txt webui/requirements.in
 RUN pip install -r webui/requirements.txt
 
 # Add files into working directory
diff --git a/src/webui/grafana_dashboard.json b/src/webui/grafana_dashboard.json
index c9092aca5..afe3ea126 100644
--- a/src/webui/grafana_dashboard.json
+++ b/src/webui/grafana_dashboard.json
@@ -24,7 +24,7 @@
     "fiscalYearStartMonth": 0,
     "gnetId": null,
     "graphTooltip": 0,
-    "iteration": 1643919736138,
+    "iteration": 1646406031197,
     "links": [],
     "liveNow": false,
     "panels": [
@@ -53,7 +53,7 @@
               "scaleDistribution": {
                 "type": "linear"
               },
-              "showPoints": "always",
+              "showPoints": "never",
               "spanNulls": false,
               "stacking": {
                 "group": "A",
@@ -91,11 +91,15 @@
                 },
                 {
                   "id": "unit",
-                  "value": "short"
+                  "value": "pps"
                 },
                 {
                   "id": "custom.axisLabel",
-                  "value": "Packets"
+                  "value": "Packets / sec"
+                },
+                {
+                  "id": "custom.axisSoftMin",
+                  "value": 0
                 }
               ]
             },
@@ -111,11 +115,15 @@
                 },
                 {
                   "id": "unit",
-                  "value": "decbytes"
+                  "value": "Bps"
                 },
                 {
                   "id": "custom.axisLabel",
-                  "value": "Bytes"
+                  "value": "Bytes / sec"
+                },
+                {
+                  "id": "custom.axisSoftMin",
+                  "value": 0
                 }
               ]
             }
@@ -219,10 +227,12 @@
           "current": {
             "selected": true,
             "text": [
-              "R1-INF"
+              "R1-INF",
+              "R3-INF"
             ],
             "value": [
-              "R1-INF"
+              "R1-INF",
+              "R3-INF"
             ]
           },
           "datasource": null,
@@ -247,10 +257,12 @@
           "current": {
             "selected": true,
             "text": [
-              "EP100"
+              "13/2/0",
+              "13/2/1"
             ],
             "value": [
-              "EP100"
+              "13/2/0",
+              "13/2/1"
             ]
           },
           "datasource": null,
@@ -301,7 +313,7 @@
       ]
     },
     "time": {
-      "from": "now-5m",
+      "from": "now-15m",
       "to": "now"
     },
     "timepicker": {},
diff --git a/src/webui/service/__init__.py b/src/webui/service/__init__.py
index 24579b3d7..d9755563a 100644
--- a/src/webui/service/__init__.py
+++ b/src/webui/service/__init__.py
@@ -13,7 +13,9 @@
 # limitations under the License.
 
 import os
-from flask import Flask, session
+import json
+
+from flask import Flask, request, session
 from flask_healthz import healthz, HealthError
 
 from webui.proto.context_pb2 import Empty
@@ -46,6 +48,10 @@ def readiness():
         raise HealthError('Can\'t connect with the service: ' + e.details())
 
 
+def from_json(json_str):
+    return json.loads(json_str)
+
+
 def create_app(use_config=None):
     app = Flask(__name__)
     if use_config:
@@ -67,6 +73,11 @@ def create_app(use_config=None):
     from webui.service.device.routes import device
     app.register_blueprint(device)
 
+    from webui.service.link.routes import link
+    app.register_blueprint(link)
+
+    app.jinja_env.filters['from_json'] = from_json
+    
     app.jinja_env.globals.update(get_working_context=get_working_context)
 
     return app
diff --git a/src/webui/service/__main__.py b/src/webui/service/__main__.py
index 38bc0f790..5dd20aab7 100644
--- a/src/webui/service/__main__.py
+++ b/src/webui/service/__main__.py
@@ -16,7 +16,7 @@ import os, sys, logging
 from prometheus_client import start_http_server
 from common.Settings import wait_for_environment_variables
 from webui.service import create_app
-from webui.Config import WEBUI_SERVICE_PORT, LOG_LEVEL, METRICS_PORT, HOST, SECRET_KEY, DEBUG
+from webui.Config import MAX_CONTENT_LENGTH, WEBUI_SERVICE_PORT, LOG_LEVEL, METRICS_PORT, HOST, SECRET_KEY, DEBUG
 
 def main():
     service_port = os.environ.get('WEBUISERVICE_SERVICE_PORT', WEBUI_SERVICE_PORT)
@@ -37,7 +37,10 @@ def main():
 
     start_http_server(metrics_port)
 
-    app = create_app(use_config={'SECRET_KEY': SECRET_KEY})
+    app = create_app(use_config={
+        'SECRET_KEY': SECRET_KEY,
+        'MAX_CONTENT_LENGTH': MAX_CONTENT_LENGTH,
+    })
     app.run(host=host, port=service_port, debug=debug)
 
     logger.info('Bye')
diff --git a/src/webui/service/device/routes.py b/src/webui/service/device/routes.py
index 8a0e1cc0a..1f9a6783c 100644
--- a/src/webui/service/device/routes.py
+++ b/src/webui/service/device/routes.py
@@ -12,12 +12,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from flask import render_template, Blueprint, flash, session, redirect
+from flask import render_template, Blueprint, flash, session, redirect, url_for
 from device.client.DeviceClient import DeviceClient
 from context.client.ContextClient import ContextClient
 from webui.Config import (CONTEXT_SERVICE_ADDRESS, CONTEXT_SERVICE_PORT,
                 DEVICE_SERVICE_ADDRESS, DEVICE_SERVICE_PORT)
-from webui.proto.context_pb2 import (ContextId, DeviceList, DeviceId,
+from webui.proto.context_pb2 import (ContextId, DeviceList, DeviceId, Empty,
     Device, DeviceDriverEnum, DeviceOperationalStatusEnum,
     ConfigActionEnum, ConfigRule, TopologyIdList, TopologyList)
 from webui.service.device.forms import AddDeviceForm
@@ -28,10 +28,12 @@ device_client: DeviceClient = DeviceClient(DEVICE_SERVICE_ADDRESS, DEVICE_SERVIC
 
 @device.get('/')
 def home():
-    request: ContextId = ContextId()
-    request.context_uuid.uuid = session.get('context_uuid', '-')
+    context_uuid = session.get('context_uuid', '-')
+    if context_uuid == "-":
+        flash("Please select a context!", "warning")
+        return redirect(url_for("main.home"))
     context_client.connect()
-    response: DeviceList = context_client.ListDevices(request)
+    response: DeviceList = context_client.ListDevices(Empty())
     context_client.close()
     return render_template('device/home.html', devices=response.devices,
                                                dde=DeviceDriverEnum,
@@ -41,12 +43,6 @@ def home():
 def add():
     form = AddDeviceForm()
 
-    request: ContextId = ContextId()
-    request.context_uuid.uuid = session.get('context_uuid', '-')
-    context_client.connect()
-    response: TopologyIdList = context_client.ListTopologyIds(request)
-    context_client.close()
-
     # listing enum values
     form.operational_status.choices = [(-1, 'Select...')]
     for key, value in DeviceOperationalStatusEnum.DESCRIPTOR.values_by_name.items():
@@ -94,7 +90,7 @@ def add():
             device_client.close()
 
             flash(f'New device was created with ID "{response.device_uuid.uuid}".', 'success')
-            return redirect('/device/')
+            return redirect(url_for('device.home'))
         except Exception as e:
             flash(f'Problem adding the device. {e.details()}', 'danger')
         
@@ -102,16 +98,18 @@ def add():
                     submit_text='Add New Device',
                     device_driver_ids=device_driver_ids)
 
-@device.route('detail/<device_uuid>', methods=['GET', 'POST'])
+@device.route('detail/<path:device_uuid>', methods=['GET', 'POST'])
 def detail(device_uuid: str):
     request: DeviceId = DeviceId()
     request.device_uuid.uuid = device_uuid
     context_client.connect()
     response: Device = context_client.GetDevice(request)
     context_client.close()
-    return render_template('device/detail.html', device=response)
+    return render_template('device/detail.html', device=response,
+                                                 dde=DeviceDriverEnum,
+                                                 dose=DeviceOperationalStatusEnum)
 
-@device.get('<device_uuid>/delete')
+@device.get('<path:device_uuid>/delete')
 def delete(device_uuid):
     try:
 
@@ -132,4 +130,4 @@ def delete(device_uuid):
     except Exception as e:
         flash(f'Problem deleting the device. {e.details()}', 'danger')
 
-    return redirect('/device/')
+    return redirect(url_for('device.home'))
diff --git a/src/webui/service/link/__init__.py b/src/webui/service/link/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/webui/service/link/routes.py b/src/webui/service/link/routes.py
new file mode 100644
index 000000000..91157a0b9
--- /dev/null
+++ b/src/webui/service/link/routes.py
@@ -0,0 +1,37 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from flask import render_template, Blueprint, flash, session, redirect, url_for
+from device.client.DeviceClient import DeviceClient
+from context.client.ContextClient import ContextClient
+from webui.Config import (CONTEXT_SERVICE_ADDRESS, CONTEXT_SERVICE_PORT)
+from webui.proto.context_pb2 import (Empty, LinkList)
+
+link = Blueprint('link', __name__, url_prefix='/link')
+context_client: ContextClient = ContextClient(CONTEXT_SERVICE_ADDRESS, CONTEXT_SERVICE_PORT)
+
+@link.get('/')
+def home():
+    context_uuid = session.get('context_uuid', '-')
+    if context_uuid == "-":
+        flash("Please select a context!", "warning")
+        return redirect(url_for("main.home"))
+    request: Empty = Empty()
+    context_client.connect()
+    response: LinkList = context_client.ListLinks(request)
+    context_client.close()
+    return render_template(
+        "link/home.html",
+        links=response.links,
+    )
\ No newline at end of file
diff --git a/src/webui/service/main/forms.py b/src/webui/service/main/forms.py
index 0dc80c7a2..abef11e06 100644
--- a/src/webui/service/main/forms.py
+++ b/src/webui/service/main/forms.py
@@ -14,12 +14,25 @@
 
 # external imports
 from flask_wtf import FlaskForm
-from wtforms import SelectField, SubmitField
+from flask_wtf.file import FileAllowed
+from wtforms import SelectField, FileField, SubmitField
 from wtforms.validators import DataRequired, Length
 
 
 class ContextForm(FlaskForm):
-    context = SelectField('Context',
-                           choices=[],
-                           validators=[DataRequired(), Length(min=1)])
-    submit = SubmitField('Select')
+    context = SelectField(  'Context',
+                            choices=[],
+                            validators=[
+                                DataRequired(),
+                                Length(min=1)
+                            ])
+    
+    submit = SubmitField('Submit')
+
+
+class DescriptorForm(FlaskForm):
+    descriptors = FileField('Descriptors',
+                            validators=[
+                                FileAllowed(['json'], 'JSON Descriptors only!')
+                            ])
+    submit = SubmitField('Submit')
diff --git a/src/webui/service/main/routes.py b/src/webui/service/main/routes.py
index 78247b3ca..54004220a 100644
--- a/src/webui/service/main/routes.py
+++ b/src/webui/service/main/routes.py
@@ -12,27 +12,61 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import json
 import logging
 import sys
-from flask import render_template, Blueprint, flash, session
-from webui.Config import CONTEXT_SERVICE_ADDRESS, CONTEXT_SERVICE_PORT
+from flask import jsonify, redirect, render_template, Blueprint, flash, session, url_for, request
+from webui.Config import (CONTEXT_SERVICE_ADDRESS, CONTEXT_SERVICE_PORT,
+                DEVICE_SERVICE_ADDRESS, DEVICE_SERVICE_PORT)
 from context.client.ContextClient import ContextClient
-from webui.proto.context_pb2 import Empty
-from webui.service.main.forms import ContextForm
+from device.client.DeviceClient import DeviceClient
+from webui.proto.context_pb2 import Context, Device, Empty, Link, Topology
+from webui.service.main.forms import ContextForm, DescriptorForm
 
 main = Blueprint('main', __name__)
 
 context_client: ContextClient = ContextClient(CONTEXT_SERVICE_ADDRESS, CONTEXT_SERVICE_PORT)
+device_client: DeviceClient = DeviceClient(DEVICE_SERVICE_ADDRESS, DEVICE_SERVICE_PORT)
 
 logger = logging.getLogger(__name__)
 
+def process_descriptor(item_name_singluar, item_name_plural, grpc_method, grpc_class, items):
+    num_ok, num_err = 0, 0
+    for item in items:
+        try:
+            grpc_method(grpc_class(**item))
+            num_ok += 1
+        except Exception as e: # pylint: disable=broad-except
+            flash(f'Unable to add {item_name_singluar} {str(item)}: {str(e)}', 'error')
+            num_err += 1
+    if num_ok : flash(f'{str(num_ok)} {item_name_plural} added', 'success')
+    if num_err: flash(f'{str(num_err)} {item_name_plural} failed', 'danger')
+
+def process_descriptors(descriptors):
+    logger.warning(str(descriptors.data))
+    logger.warning(str(descriptors.name))
+    try:
+        logger.warning(str(request.files))
+        descriptors_file = request.files[descriptors.name]
+        logger.warning(str(descriptors_file))
+        descriptors_data = descriptors_file.read()
+        logger.warning(str(descriptors_data))
+        descriptors = json.loads(descriptors_data)
+        logger.warning(str(descriptors))
+    except Exception as e: # pylint: disable=broad-except
+        flash(f'Unable to load descriptor file: {str(e)}', 'danger')
+        return
+
+    process_descriptor('Context',  'Contexts',   context_client.SetContext,  Context,  descriptors['contexts'  ])
+    process_descriptor('Topology', 'Topologies', context_client.SetTopology, Topology, descriptors['topologies'])
+    process_descriptor('Device',   'Devices',    device_client .AddDevice,   Device,   descriptors['devices'   ])
+    process_descriptor('Link',     'Links',      context_client.SetLink,     Link,     descriptors['links'     ])
+
 @main.route('/', methods=['GET', 'POST'])
 def home():
-    # flash('This is an info message', 'info')
-    # flash('This is a danger message', 'danger')
     context_client.connect()
+    device_client.connect()
     response = context_client.ListContextIds(Empty())
-    context_client.close()
     context_form: ContextForm = ContextForm()
     context_form.context.choices.append(('', 'Select...'))
     for context in response.context_ids:
@@ -40,12 +74,52 @@ def home():
     if context_form.validate_on_submit():
         session['context_uuid'] = context_form.context.data
         flash(f'The context was successfully set to `{context_form.context.data}`.', 'success')
+        return redirect(url_for("main.home"))
     if 'context_uuid' in session:
         context_form.context.data = session['context_uuid']
+    descriptor_form: DescriptorForm = DescriptorForm()
+    try:
+        if descriptor_form.validate_on_submit():
+            process_descriptors(descriptor_form.descriptors)
+            return redirect(url_for("main.home"))
+    except Exception as e:
+        logger.exception('Descriptor load failed')
+        flash(f'Descriptor load failed: `{str(e)}`', 'danger')
+    finally:
+        context_client.close()
+        device_client.close()
+    return render_template('main/home.html', context_form=context_form, descriptor_form=descriptor_form)
 
-    return render_template('main/home.html', context_form=context_form)
+@main.route('/topology', methods=['GET'])
+def topology():
+    context_client.connect()
+    try:
+        response = context_client.ListDevices(Empty())
+        devices = [{
+            'id': device.device_id.device_uuid.uuid,
+            'name': device.device_id.device_uuid.uuid,
+            'type': device.device_type,
+        } for device in response.devices]
 
+        response = context_client.ListLinks(Empty())
+        links = [{
+            'id': link.link_id.link_uuid.uuid,
+            'source': link.link_endpoint_ids[0].device_id.device_uuid.uuid,
+            'target': link.link_endpoint_ids[1].device_id.device_uuid.uuid,
+        } for link in response.links]
+
+        return jsonify({'devices': devices, 'links': links})
+    except:
+        logger.exception('Error retrieving topology')
+    finally:
+        context_client.close()
 
 @main.get('/about')
 def about():
     return render_template('main/about.html')
+
+
+@main.get('/resetsession')
+def reset_session():
+    session.clear()
+    return redirect(url_for("main.home"))
diff --git a/src/webui/service/service/routes.py b/src/webui/service/service/routes.py
index e41be7c4c..17efe1c09 100644
--- a/src/webui/service/service/routes.py
+++ b/src/webui/service/service/routes.py
@@ -13,7 +13,8 @@
 # limitations under the License.
 
 import grpc
-from flask import render_template, Blueprint, flash, session
+from flask import current_app, redirect, render_template, Blueprint, flash, session, url_for
+from context.proto.context_pb2 import Service, ServiceId
 from webui.Config import CONTEXT_SERVICE_ADDRESS, CONTEXT_SERVICE_PORT
 from context.client.ContextClient import ContextClient
 from webui.proto.context_pb2 import ContextId, ServiceList, ServiceTypeEnum, ServiceStatusEnum, ConfigActionEnum
@@ -29,6 +30,9 @@ def home():
     # flash('This is a danger message', 'danger')
 
     context_uuid = session.get('context_uuid', '-')
+    if context_uuid == "-":
+        flash("Please select a context!", "warning")
+        return redirect(url_for("main.home"))
     request: ContextId = ContextId()
     request.context_uuid.uuid = context_uuid
     context_client.connect()
@@ -44,7 +48,8 @@ def home():
         context_not_found = True
 
     context_client.close()
-    return render_template('service/home.html', services=services, context_not_found=context_not_found,
+    return render_template('service/home.html', services=services,
+                                                context_not_found=context_not_found,
                                                 ste=ServiceTypeEnum,
                                                 sse=ServiceStatusEnum)
 
@@ -56,8 +61,27 @@ def add():
     return render_template('service/home.html')
 
 
-@service.get('detail/<service_uuid>')
+@service.get('detail/<path:service_uuid>')
 def detail(service_uuid: str):
-    flash('Detail service route called', 'danger')
-    raise NotImplementedError()
-    return render_template('service/home.html')
+    context_uuid = session.get('context_uuid', '-')
+    if context_uuid == "-":
+        flash("Please select a context!", "warning")
+        return redirect(url_for("main.home"))
+    
+    request: ServiceId = ServiceId()
+    request.service_uuid.uuid = service_uuid
+    request.context_id.context_uuid.uuid = context_uuid
+    try:
+        context_client.connect()
+        response: Service = context_client.GetService(request)
+        context_client.close()
+    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'))
+    return render_template('service/detail.html', service=response)
+
+
+@service.get('delete/<path:service_uuid>')
+def delete(service_uuid: str):
+    pass
diff --git a/src/webui/service/static/partners.png b/src/webui/service/static/partners.png
index f88680212f68cdb4c17ad0de55b9d22ef9276a23..0c2b89eb9321caf8d1f1d63e0e20fd3e4b6ddeb7 100644
GIT binary patch
literal 200855
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
OgOOL4dnfxK;Qs*KL9tE%

literal 76488
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
AtpET3

diff --git a/src/webui/service/static/topology.js b/src/webui/service/static/topology.js
new file mode 100644
index 000000000..dd58388cd
--- /dev/null
+++ b/src/webui/service/static/topology.js
@@ -0,0 +1,148 @@
+// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Based on:
+//   https://www.d3-graph-gallery.com/graph/network_basic.html
+//   https://bl.ocks.org/steveharoz/8c3e2524079a8c440df60c1ab72b5d03
+
+// set the dimensions and margins of the graph
+const margin = {top: 5, right: 5, bottom: 5, left: 5};
+
+const icon_width  = 40;
+const icon_height = 40;
+
+width = 800 - margin.left - margin.right;
+height = 500 - margin.top - margin.bottom;
+
+// append the svg object to the body of the page
+const svg = d3.select('#topology')
+    .append('svg')
+        .attr('width', width + margin.left + margin.right)
+        .attr('height', height + margin.top + margin.bottom)
+    .append('g')
+        .attr('transform', `translate(${margin.left}, ${margin.top})`);
+
+// svg objects
+var link, node;
+
+// values for all forces
+forceProperties = {
+    center: {x: 0.5, y: 0.5},
+    charge: {enabled: true, strength: -500, distanceMin: 10, distanceMax: 2000},
+    collide: {enabled: true, strength: 0.7, iterations: 1, radius: 5},
+    forceX: {enabled: false, strength: 0.1, x: 0.5},
+    forceY: {enabled: false, strength: 0.1, y: 0.5},
+    link: {enabled: true, distance: 100, iterations: 1}
+}
+
+/**************** FORCE SIMULATION *****************/
+
+var simulation = d3.forceSimulation();
+
+// load the data
+d3.json('/topology', function(data) {
+    // set the data and properties of link lines and node circles
+    link = svg.append("g").attr("class", "links").style('stroke', '#aaa')
+        .selectAll("line")
+        .data(data.links)
+        .enter()
+        .append("line");
+    node = svg.append("g").attr("class", "devices").attr('r', 20).style('fill', '#69b3a2')
+        .selectAll("circle")
+        .data(data.devices)
+        .enter()
+        .append("image")
+        .attr('xlink:href', function(d) {return '/static/topology_icons/' + d.type + '.png';})
+        .attr('width',  icon_width)
+        .attr('height', icon_height)
+        .call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
+
+    // node tooltip
+    node.append("title").text(function(d) { return d.id; });
+
+    // link style
+    link
+        .attr("stroke-width", forceProperties.link.enabled ? 2 : 1)
+        .attr("opacity", forceProperties.link.enabled ? 1 : 0);
+    
+    // set up the simulation and event to update locations after each tick
+    simulation.nodes(data.devices);
+
+    // add forces, associate each with a name, and set their properties
+    simulation
+        .force("link", d3.forceLink()
+            .id(function(d) {return d.id;})
+            .distance(forceProperties.link.distance)
+            .iterations(forceProperties.link.iterations)
+            .links(forceProperties.link.enabled ? data.links : []))
+        .force("charge", d3.forceManyBody()
+            .strength(forceProperties.charge.strength * forceProperties.charge.enabled)
+            .distanceMin(forceProperties.charge.distanceMin)
+            .distanceMax(forceProperties.charge.distanceMax))
+        .force("collide", d3.forceCollide()
+            .strength(forceProperties.collide.strength * forceProperties.collide.enabled)
+            .radius(forceProperties.collide.radius)
+            .iterations(forceProperties.collide.iterations))
+        .force("center", d3.forceCenter()
+            .x(width * forceProperties.center.x)
+            .y(height * forceProperties.center.y))
+        .force("forceX", d3.forceX()
+            .strength(forceProperties.forceX.strength * forceProperties.forceX.enabled)
+            .x(width * forceProperties.forceX.x))
+        .force("forceY", d3.forceY()
+            .strength(forceProperties.forceY.strength * forceProperties.forceY.enabled)
+            .y(height * forceProperties.forceY.y));
+    
+    // after each simulation tick, update the display positions
+    simulation.on("tick", ticked);
+});
+
+// update the display positions
+function ticked() {
+    link
+        .attr('x1', function(d) { return d.source.x; })
+        .attr('y1', function(d) { return d.source.y; })
+        .attr('x2', function(d) { return d.target.x; })
+        .attr('y2', function(d) { return d.target.y; });
+
+    node
+        .attr('x', function(d) { return d.x-icon_width/2; })
+        .attr('y', function(d) { return d.y-icon_height/2; });
+}
+
+/******************** UI EVENTS ********************/
+
+function dragstarted(d) {
+    if (!d3.event.active) simulation.alphaTarget(0.3).restart();
+    d.fx = d.x;
+    d.fy = d.y;
+}
+
+function dragged(d) {
+    d.fx = d3.event.x;
+    d.fy = d3.event.y;
+}
+
+function dragended(d) {
+    if (!d3.event.active) simulation.alphaTarget(0.0001);
+    d.fx = null;
+    d.fy = null;
+}
+
+// update size-related forces
+d3.select(window).on("resize", function(){
+    width = +svg.node().getBoundingClientRect().width;
+    height = +svg.node().getBoundingClientRect().height;
+    simulation.alpha(1).restart();
+});
diff --git a/src/webui/service/static/topology_icons/Acknowledgements.txt b/src/webui/service/static/topology_icons/Acknowledgements.txt
new file mode 100644
index 000000000..c646efdec
--- /dev/null
+++ b/src/webui/service/static/topology_icons/Acknowledgements.txt
@@ -0,0 +1,12 @@
+Network Topology Icons taken from https://vecta.io/symbols
+
+https://symbols.getvecta.com/stencil_240/51_cloud.4d0a827676.png => cloud.png
+
+https://symbols.getvecta.com/stencil_240/15_atm-switch.1bbf9a7cca.png => packet-switch.png
+https://symbols.getvecta.com/stencil_241/45_atm-switch.6a7362c1df.png => emu-packet-switch.png
+
+https://symbols.getvecta.com/stencil_240/204_router.7b208c1133.png => packet-router.png
+https://symbols.getvecta.com/stencil_241/224_router.be30fb87e7.png => emu-packet-router.png
+
+https://symbols.getvecta.com/stencil_240/269_virtual-layer-switch.ed10fdede6.png => optical-line-system.png
+https://symbols.getvecta.com/stencil_241/281_virtual-layer-switch.29420aff2f.png => emu-optical-line-system.png
diff --git a/src/webui/service/static/topology_icons/cloud.png b/src/webui/service/static/topology_icons/cloud.png
new file mode 100644
index 0000000000000000000000000000000000000000..0f8e9c9714edd1c11904367ef1e9c60ef7ed3295
GIT binary patch
literal 8988
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
O0V&C;%T`KbasLBlgSHX?

literal 0
HcmV?d00001

diff --git a/src/webui/service/static/topology_icons/emu-optical-line-system.png b/src/webui/service/static/topology_icons/emu-optical-line-system.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5c30d679170c6e080dee3cc5239bf7ecaefe743
GIT binary patch
literal 12869
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
Xyi~U~2mVO}4^Kl?SEW`N750As2d5jB

literal 0
HcmV?d00001

diff --git a/src/webui/service/static/topology_icons/emu-packet-router.png b/src/webui/service/static/topology_icons/emu-packet-router.png
new file mode 100644
index 0000000000000000000000000000000000000000..95fc8b9f35a0cda9440a07ac0df3d0d417cdd0f2
GIT binary patch
literal 14197
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

literal 0
HcmV?d00001

diff --git a/src/webui/service/static/topology_icons/emu-packet-switch.png b/src/webui/service/static/topology_icons/emu-packet-switch.png
new file mode 100644
index 0000000000000000000000000000000000000000..f9d431cd29b9eebc7eb6ec503ba8ed777082fa21
GIT binary patch
literal 11859
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
J)T3Qu{twBB(<lG{

literal 0
HcmV?d00001

diff --git a/src/webui/service/static/topology_icons/optical-line-system.png b/src/webui/service/static/topology_icons/optical-line-system.png
new file mode 100644
index 0000000000000000000000000000000000000000..b51f094216755ed9fc5c7a7e8957bab88090c954
GIT binary patch
literal 13777
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
NsVZqIR>@mN{6A11CyD?7

literal 0
HcmV?d00001

diff --git a/src/webui/service/static/topology_icons/packet-router.png b/src/webui/service/static/topology_icons/packet-router.png
new file mode 100644
index 0000000000000000000000000000000000000000..5d2ad4dabe730f78206afddb21886c6678e88a26
GIT binary patch
literal 16162
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
Wi5x2LQ^4GJfP{$b&k7-Z|NjB9bjKh7

literal 0
HcmV?d00001

diff --git a/src/webui/service/static/topology_icons/packet-switch.png b/src/webui/service/static/topology_icons/packet-switch.png
new file mode 100644
index 0000000000000000000000000000000000000000..14f81111f9fbb4236f60f92cac1147365112bc41
GIT binary patch
literal 9777
zcmcI~_dnZj_kR+rqEr#oZq-c8R<)>6RV7x9h}MYJVbo|)qlnSgu9nc6rLhtOwO2aO
z($d<SBDNYeYJXmNzwi5gJidRx_Xj_?Ugw<ajO#k*dCrw66C+(#C?6CA0<r4dylx5t
zff2O76O6!$|C4wh5J&{1cU{Z;vF%C*a}unjv9(#~F0Yg3P<5zCO$@)J@y#5CFN%mT
zD4){0-e=ZuB$wkw76n;jM<HqU&(EL_Yu-}GtZDkO1&FCIsB{<$?+e2!oPFMS;gYrD
zw^7v{Uq7Fn=K5xJiMdA3x~kHq{f>dFeHPr0#kfrLedvEgc$<Kw*;65cpjZf5fRX{~
zzm2cV^Y$Q7>ck7|3BB&1-;6Ir3+^mKVbAL!r_gw%FiMe$rj!K}<rRprZS0JI28_Lc
zA`Oy2<1O&ZcicGfrbV#ObD#`*Bd+@E3<Z=^&`~F={_rwJ-~)fCCFo)<yZ{7aCsJHM
zZEY&{QiP|V$JWbSWsc^d(DSh8JE{mm?<dgH{6C-Cx9-S0v^y-1giI#B?tcq0r;s6n
zZ-k<m7=5%4RVpv^1vNWcHOGu0{RrltqID@1-BK418!P|zP5&tioH#N#w=q!&f_WBD
zz83R4j>paA*lPt}QabovPP*gB0PIo*x=VLIMgJ@zH1Mw6r!P5TLnpoj0=jt?gc_n3
zP*XG-5XhLWAVuFXBM)2Dy%5a<%Z7|gy<kS|cXTACnYo{F3JN78?TLmqgKpMhr-{X?
zKSRDD=66sHfSffWoB{bw-4x5FS`+JHe`oP<)I1$h%7TYd0m9bl`^(t=k?GuT6L1^1
zm>NTr-Idm4c)>~vUJrRx=G+Tgrvn_u8fpdF^utM&>Uji*xn^3?3u^h_0!vS3K!!dR
zk*w|awY8@iNYO3XJ>ZK*N(_7^%}>@1V*^*TSMNSoG6PG$Frl!KHV?}nc+*8bP(Yl8
zt#q^7SR+rkkW_1q@j#Ce;Pl5NO>y+qt$u0i-CoxpU#0z9AZUH5L;UYspn$D_cGte@
zkslu43`k=QpQax;YylijbVNJjfXX)}iA;D?eT}^ZUCl!qOuOs$GrOsm%zwy_Jft#!
z(1*4`FGpI;2s6Vkjr7P3Y$3Ok2Ci1%?Pp@eez0i&V@EOMAqMsUV}W4o>)_tph;-rM
z2@h~J=r>|0lAh#7CDH@(<v@KSdE*~ivJZZmfX_fvLoH?ipLb{VtDVX=u6r=$U~-1>
zuG~~^s1#ZUO4Iyj`O#ymkk9EGQw~4=9^AZa3NS@jIMJ9!KFnumZEef<$u{zC&hkur
z)~Mk%e;P9sgO<ebp%OuWn*u-~OeQNaH?L~SGRC!dgoktGh4PT0O5`Nd0RE4<0DY?2
zP{ts95=Oelf*>TRb2%`E_Vm<-$7neo*S`gUB`3v5*O-B`QwSq>w|Nj6erGfagvbUw
zi_xN!N2JA;LTo=tV=1Qk3*iP^xV$|~kBg<=gELPJte>agLxk)GJZH>BKnw?=7WYFf
z%6K<zK};F3xBP84JG18!(!ybOPk1QUGCgT_JBEWW3rWB%6)uVspzP|YFwqoZXcn2{
z6tH_DEJkbV*wEigp}_h=#l4>>iU&FhxP*%WAT!W>gvCmCjFxW0dtOJ|Ly_T<$@zj%
zO@^@0WHd&K@Q~3{IP`YmY;=qkgG#DRbR0zMgT4S+nmb&bZL%9%(Uqa)_@{nSlR=vO
zJn1?ZDMc8tFr+$|;AEXs3N*QyZp>dDG;?=#GgUi%=RBOS8ST^PZBvRd_CM@Or~d81
z$}%cl*(Jq5ors#ic^m4Y;DFF1gzPDpgz%$RfT+32wCopzDnoDLEV2_K^a}+*A#`ga
zSjEzbCKkHZ&RGW&kDxEN3pH;roc|y#|IhJ3a&LA=CJl7^@N<%fYaESl-14UbF6%7p
z1tU?D7JAh%Zg7E@!aVtF4B0~?AxhapyZ<JGB3$G&stLH2gq_<1fh9|g14Ns>h=J2)
z+>V<ccP_x&RcRObI=GO$0YmE-j(|p4HJj^;d;zaYj5`v{DR{_Bdnya<aKL#R#bU?#
z#HlSU*;Q&SX@#K@(3{Va=O{(!lSKoT3x+$UwxefyIakX}r7=jHJf+<X@O7O<y3;FP
zh55sl)u~fG<FlRFRU{g(6~jjeybDmA4>I`^D>3A$P+;|`?2`1PIgnJkb*IPH4)~3T
z%C?>J`hJ9@aT|NC&|eDy?Je1@b1z_~U|nbgE9wT2jP->bicVeVd-f);p@z3Nu@wCr
z%4;bSOIBp0rH#GR$4{(-+Lwm>)LW8`8)@vtZP3Eds|+8Za8XM8U4{8#Il0zPEC6q2
z@ndC}e5q!tJr%fSg$kg({-h!-U7GLj4{iKaZ!9yFOu;n6!iH-v7y59{^y%07@^{;k
z^Z7=rm`XLZf^GXk>L$ub;YPjX(i3l!idZJ$pg1?F)-)hXvlnXeVyKcpIT!||GGyo8
zqz*{|`Or;@of|#Gh-z{8u>j&5F^y0LlA4Gqu5J7;?||B$x-U(HMf3h8!2OnBUg0;1
zWx2HUWS+h7-54|SyYbBGD{t*Le&`)5JVDv=vZs}P;Xn~~j|=q7;%Id{CE0PV$yCbG
zQ3Hr^fk}3@uWftE%J+xCkbwLovUR*|-O>js!Z`hp$_>rAC!4Un*vvEdvWhHokxNj6
zrgESREt<GDeE0B&-0_WMLR)EYpai9GF#gg<*{4lHDGnc_L*uSQ)JSS#PNTinRoc#g
z8BQP|aLA=u_Ng2YP6yM{vLtYio=b#$f^=dqRr`4igq|A*<0*ZVPUAmEK8JB+J1Yxi
zN7JLM8#=viXo4Xzl>ZMx;WHGK^Kv|a`a8OmXo0W^Xv9xddK7T^;B6m|*^U%!?HYyT
zn(JFVN-G*qNXk>+jMw;Wdn0VB6)xtUC0{#1V)Su!Z0~FIn*CYq`78I)Iur+cBb@#&
zUY5^GNJV&@UOOuY_9`VvywLT*{xwYGNwma!mxu?Spg*g;4nMzR6S9jfgg2dt92(TK
zf+F}7*lk9tZ(<jJMXpZI@@)Ad%H<&N>y*V1Q&qLCrQecYx>P5nA;|4h2HvaEbjY1Y
zA0+Iib9Cn%_A{S2)Ei<V>Cqv}fqa`Gh$W2NdZNj)2QsK_Q`CN7`}?WIxqJN8xf7|c
z{|5E!oZC0XFf-we%w9b`5TG+sKS#hZ#>ur_ROg63@X}lDU8+8Ly_!u!jRV!xBscUd
z=Ga4MHh43+<}5op4A)n6>xn^Q3A^AOC4E-`afDZM;SX%VqNqJJJ_Q~*VjIkoJKHSb
zqDGH5!5nTD;G>%9FCo5^{*<T37fhHHsF-n*U()$+XBcya=pba^JPMZ}ND=bWLz3u`
zdJVt#BX7kw5tMex(;hc-HH-Yvg%54&d__A2Raw$}@$@BPII$Dx0EKzcl+4JEdcm|x
zg%czaVJgmo>kBu!Zg9`NULLcIApH$^l&!*nz82c|-d1ovxy{C`fxh_bS$b4<bC!wn
zLnd@UwisdGYxi?xYPnjC9Q*_VOi>~DI2zQKoVu+fNj{_#A-f@4Au#A51IqOB;gzne
zm~oux5mFDsaFWELQrY&oBP3qMzc&7E7RCEKKMU9sijWy!J~i-b3IGDGrOm?QoM<o@
zDF<qFrG)(Ix6QBHTW3d?%*6QED^t2ZKG|47ZSr4bS*luIGt`B^K^WM~oWsTsA<5;z
z{;lhr=n}D5cZP>JLgYxDtDG#a2Gj8YHe3#{Nu7?U-J`AGgFYMY{`1EddQS8Wr&wn(
z@lZk}94^<^XWSgG7h~yPB8sDml7oYn6V|3I8a?OFR>m13aLxwpgBDIuwBD~)x!Y0v
znIUw})bYkR333pm-*7HHHn2;TE}%I1YYauP@NUDRA}gYJJg0AoGvWD&Z(zkV9geC%
z-f*E}K04o<ekrT#zu_uER!dakP7VMgWJZU-tN!rVG$8HmT$%<n6@n0{_CD(yN{wE(
z>+iNo$Xfl<<*%Al1!oyJ@lD=wJ&IG!Ysy%tx_KBl!8tNjebtCtHP3AL;)l0B-x@Ou
z)JzU-mvUL}l=<w8hqs0t)m$mr9yv!=gP`WB3>6OR)bFE?*~^}8RX9?q(6)qhgm0FZ
z-22C?#ynGh@e6*#YdMAsK2-t=Kl_d;fHI(^sh$J_HAVoBij8SBZ5xN|9#0q})+)be
z^YM??(q#$`ix$kbR3R~k@=7DZe9?84L>cbmG-s=7RAz&VM?<m}hKlC?-JA`7I3N5H
z{fU04>@oq7N9;8cB}ageSx$dOe`L-FTQ7;c7HL|!{0{iEd1?93<TQ8CMx0~TM&b|6
zk1Bcobl-T#c~+#2%DvS16(o6|CADCa$G_}vr_`#TVkzFtq;Uy>%)j6AY%`A2ojB=!
z*YG(cnQ`}6`1b#}Bex`zx`q1YD+}phAP3tGGW%tYw8W1$@M!)+vdt}LyDKL9T3&eX
zM~s^sq~k1k6MQ-*Bt-p9|8#kz+jrD%lVlzu558|C84x0~IZXPO=sg8!FP={E?`wUE
zNx909lUklyvh1%ZK|%_rdAOdH!cigUfPl^Z))wXMwkQo3H;<~v$~j3isxy1IS~!QD
z`kG+BR^4s|8__mc=q}r8+J=dKU=MF;eJ+iv{Le!G=*ec)P}ZB)4A8QiDDO8ebF-6?
z!~m@jjaGOdL(U5tS=OphZr*fd-%^E~3DpSF!A^c(5->8&+^oW%;&ZiiJ>qjQhRYQ2
z#dZl*e@FN|$NB>!@8RD<^TDOt%QEaos-MznI_)M<I8GqO2(Dc!;8Ql6oM;u_^`cui
z`Fz0gz*%u}1O(}~^s!S={=rSZnf~^mnTEy($6aGutIztXyq<`5sC-N<2WlMX(5Pjl
z62SEMklL^AN>v?!wZf<eug6chA}hsMMo%H-$=HF;D<wV-oXy%r9%A+*m_jIh<8*;K
zz3*4SaGM0NSg8*4y1GZLrUyQ=rUQJ##T25Tu7-6p!(rRE&jWY-hE_~l_jkL;CXqW>
zm#qFOsk?R)r&t$f@1?WXE7P+g#wILFWUe>A8a?*8Xdu<mTTgVa-^m$UG2RUpDa=%s
z3spL7lw0d)<Hi^lDl?IQ+yFwRX|K-9ujU=y_fI{Xo_7sPrN^`=I7eQ!dCiDFdb->B
z8tIkNrk6<BU`7v%6!UXqfCh2u%iU)~tfmiEQ$VB|0!i{6{1s)`$~3wo6Ae1F$sXXL
zrIJmjOVVH3()stMdoLNrek<m}v`9JYoV9rk!KX;fyxYUE1E~pV95&vuOCScmZCiJ@
z)<#0fQ!mSNUX~buI+iY+U`9}Su8ytz&=oEyN>Q`M4k!9XThv=}kf&bIh(;l<0QOV>
zT3=&he{nKB7=GnUfY$;!%LjW>MvoF5&>n4C=M6<v-w{x~6riJ}&cV2L6YbOeaA}M=
zL~zn=&h!B#+WQ|O2q{i=dvdg_g6x)Y9Ao{e`3wXJ0!%nqjLqc~Hkz9m+)vWwBj>y+
z&%u{0LtGbz<1Qa3UKu1msUCSTQ>2CyqelmD?_<@}%5)5aZMT`o`t&F+GgNPPvLI%G
zp^;YD_a3EX%R!L9Aw5%9<&imfk{p~dY~`<gj+}!p&jF4z7-d!a(Y>@Gl4-6vC7I{2
zCW^wrh`72ytDJ82qom+jI@xy+xV{uTdSQ_X!+L#STgKG;?ovtP-<F74^!(HhGda)=
z3^P4GbKcjGO=o@U@JG|aTcytZ$@P|0pud)D_*K^_8RW>@hqd4&tB;dmb8%_mUCQo$
zE8rd&JNg=qAfb{5Y$A>rJC=M$D##;Z6Cx@!te?e5d}En$Ty~oT#53YEDSJK}9Q9|@
zeXzu&KUeMtDdaI5qU}RcU{ow&Zg%SqqY&1!9cW>Hb?G3>f8D_Bu%kcXlCiBUmRq0w
z^Q%hla(zvRus624Wn`Hw%)Et?*A|z>2EB~S+B`?T1|eaYtZxRNH{iPxyIP);S@JR=
zqL`oS{H2jQwf4lUQLj+|{BdB!?mc!o?(x#i>SPkP-V?P)1K#dQ&g6N5ZZFtf{Z*eK
z77w2C(}KXADBX;;Q*CYbqlA0nY&9peKPv9ZF1@a{oZg6Hxq6uK`K*n<boR4kPV`xN
z{Prh`Sv;jeyXylXL52cfEm{9@?rsrVkKM`X7bV}m6&+Wyqt7zntJ=HbcTaCTa((-l
znsTJtrWKPn?(F{>NCUq^ziN+VMR3m8uCV2aU(`84VyA;&lqJsJ=LIrRvYX{;G(EnQ
zEt!^if-1vuTLGxsk?57q{gSql-dPkvrLAaGTf9H7;H+S?`;bnTl>^`rovxAkXQlS_
zt>bpuO2|WE@5^^UJ%BxD5Kz(w&~tq3bkz&m3f1@0A>0^PIjSwzM{>||Af{)vz#hQG
z-cACXk>`PG1LwT3U?&J5X=>Jp>HCWSK-kM1?Dr8)Cj~1fm-yn7a<<%GeSR1)ciUPE
zI2-^L@;#~O{94~KB%_wguM^Ez5byOM9f04Eod9;J4yQU7zkRd8rh9giDy?tnXb8Qg
zEBvOFfhEqkK9>y;0GN;}J9Dqyp-%B?;8CCMzv?~39~b~c=ki8xN&M@J2FV#+fM~;E
z_JH^bkbm&#4nRbc<d8RVOZPuS(lgF9BA5OHV#>cn+%iA}fP0h*`c+Na?s7~(BJlrb
z!-`xsn%70AA6tEip?QZIyKAWoG#0yam-uB~8(3XXN8g({FL3x>#IkZE_4=uYV&oHu
zQ*P8I{Z~@1-~A@0frMB4o2&T@R_5&zl%_ysR6`NPyj}692H;2Oy3%k!h0*#ixqJo$
z1m~Dzo#NY^eH9vEV~iR}>l#f{&oFnCAz<?*nd#LPT1b+cAK99@0*(@Ei+d2j;RF!9
zbUp=y=q2?FS0l3`5dE*^On{nSz29X6YKwL8(TKZ}uhE#*Txm9{Swd-!QFPY=Br9f|
z@uUfPz(NzU@C^jufMjbVjn3MSkycq}ZifMi&eUB9rO6v%qsbe2t4^zQL%u+Ng&1Pn
zqMf?0)ezdgeuc(TF$?-lFu)RI6Y>ddt6yX=@G0_Bp-?_ap)@!&&GxV5{mSRaHfEq_
zdvDvEZ5F8J=WHx`7!tg2?=RKyPh4+{euEjUPiuIT(x#NA!mR68(O~`SZ{n-<-MrPS
zzm<r7xwJN~cHJ1`Y?w!!5y=b=R08Hayo0HOo_GIg1}l*C<MxU+V$a%=#5{9|*eIGA
z_3!mhHQux|u=<})$pH&Gbq?*&XRLt6Z~>#@c|yuUv=s7x7U%=i8^yFvbHirQ5g>i(
z&O~$8ib+-v%na|QN^_RmGsYJsspbE3RyMXJNo;_F=B$AXa2`Al@w$rUtk<0<FWV?M
ze|^tDa~3u)lt%ZzAaw)s{ud<LzU9lbAe9S9A!tnhjqEQhVaFxp&mY!#|Bt^)+P)r^
zTO;S|Ahet6eojtWzEU(?o%!Bgv>bUR{zFOq|NFfMmO7mHc0=!S&r?`VSCqSrU$Rt3
zWkiWIO+8D-jU4h<tj}C5Axbv0yH3Fj&-04<C<CyAT0wPr*cpROc1x5(_L{3Mo&+qo
zq8M)(*>KbHYm=h0zmn@w9}-aas8&WBX-l(Np=Y^Bl*ZexDb5o38gP(7r@5yOaI;XJ
zzlpu&!Zb&JHm_f#r^Qn7Md8QbcL1AN1<d*?zy?d-m%hDy0Wh6GeXK-<7J`zKPC4W(
zfUV<mEQ2NOq%+K^gS6hkd!&{Mt5MSfueceD9Ig2zfW}|5QRq4?ve<STC8K|MXY$r|
z^Q+qaSZ-m>baLFN9*irfyDnR*W_TNF#uzR6b*4LJo4=sRr_eK+(1OH(QPsRwH&sv4
z%p14J{nr>H79{Nq8Qqhs@uscR@1G|CdQap}ScLzF0*a)?&*-jvjUsJ@xPPAJ5IdR4
zA_ZEUoJHy*#b_(_6}+Q|G>WwS^ZCTfc_bD8N)yxDvm*y-_n!kN*5I!sQRUw+JSB@!
z8b%>Z#HKNP-+>-b>(7yc*6n$_Eli&;3~XuH>+a0)>f0SQ-T&-=xkQJKOI?i)IpDt0
z!t{_Im?f~0v^TuV^0Cc#gdf|E1E|rpU-5u&KPvw)u48;P=Eg}HI3Nd31fS%yi}e?N
zLM<#2mzE%3J4t#bx5vy~vd3s<8D#&FCA05z9u}6Lw6!Ng_p?|#hVIW1v5jZ4RxB%E
zmW~rftBI)Gu%L#=7INwSSh)4ydFzIa-+Y|5YovI20`YQVM|VPm&4{vw{HngxC@^c|
z-PzOcYM88YpcUT5zqvP31KiIJUn<E;4HTs2GaI4p4J^I%tSkUbKf3eXDqh1NuubNU
znv^jn@&tM=bCk`PZ6QAFpn>i#uUZotm`3pSSXi5)HUv@9<!VQz30_-0rGXGZ<zx=@
zSrFbC9P-;w<)Pg2$-`sIrt=ycPp{atoOSM_M_fI6Elm0pnZWHhapbKWt8g1n;b0>L
z?E0r(e5VS$D){IHpFjDiE?T=?f9EE8=$=PV6&M(qw(f}S$A+~%aHhv&FqQ7+!WW+I
zd?=IQ%geAUWQIc*q!*=#ivau<-=9qTKEH)IeQ5>Z)qchiDB5o+dkeQ@6sU{i_t7ux
zrk#)sD6VdcUNck`rCSAf6`-3tSjCb?%0KZ2rJG*|U|RpynDNKMIX|7^bZI$~={NFq
zjE<Cz&K2h&Fuvb@I{s?ZyRBb)GDc{}cPD9M4F5`R`CsJ~UV16H<(bw|6ad`<@U@%;
zQQQ*$^2xkvfH-&Qu3x{9lD{Yoj~XuZ;f|iJy!ZX?_Pz8XMn}O$N6GmLAlkv>!I|LQ
zzXzK59(FV&w6E6PtRcwI<GqUsh6S~E7XZZ$b<r;E0CFyVW(x~hxe&89*sNZ)Vx`P*
zf)tALSzpi<7ou~W>-WBx@G=xe#ll*WsEla6t2el1K8#i1uWXdOx<-%Eq_meIM*WV?
z)U2n!%J?>dQ~WQnGX#A*h1nx0>E@kaYkCxj;$l*LDU*Mgb1cDiB_N&vg0n41yGV6#
zk>AVi(H$VgzqK8Cdswz`0v*Fr>MX0g<72z`#J`V+WXj(Cm-amQ{iV|4Jx01C1=X@<
zyyZVVNI;h7W${xhxB#D{KkMZqQOO|EWdc!>fasxg4>#=h`OO3EcGdFmQva}22Ou51
zv=f=JmU3iM^rT_g7bOOQ8!brdOLeed9z0PWsS&&?lpbGN{oC7h)rHE8NWc-Q<%9R2
zhwB@sTP2Jwc`uTuQcH4PmN!7~{r5g?+srEzogf~$Z-=r#I<zsB57D7H6Pr41s5mv8
zMUwQEW2tXX!0X}tF>Ld@KEJOK{*S$e=5EyKVEpMx7lxIMmroAY*b0hr!l?Q*GzRo>
z_WMF-?xYU>9PVXS^&LJr(zw%U`&7eF`H|-d92HD1QU609TesHsV}fy`outXzlf2+(
z_1XfuD(Fn5)-10xJpQ2BevW(+f?O?G`$D+)YvW<t(*Yax9kp)@?VI(8EW%FZ6*DGl
zcJ$Lwf^qrJgisr}VA>2(^xE*C&4rXHxeNHG?{_q?cS2b9`rUaV0!{||9IgIAO;)8$
zc#jI;oI&V4>Qcu5caC9hK)l4cc!peB9bH!4`PxGC?CU9gOR^r4HNe!;_cLS+J5EtG
zbTb;PN2b~uHB%>SEHYG&T7G1vZAtaaX(%#@5uB@_>Hw0MpRn#D4grJerH3Be#NkB@
zUfCmXEjrw&xk%EN_OeN|)~S?HOJ>20DP^++57Yw%V8%Te_S_Vx7v8fgEv`*1wT|~3
z(^!982cwl5uC1}5b(K9pPZn=-%HHvu>6dJ%FH%`EdZyem(mYp>P<{G%cBQW-XzC*=
zCPENx6MsMc%D|5HVQ<!)KNF&uY|E?SjuuYut@G*+`*TAinpR($D)JF_;daKi?=Lwn
zU@0!a9h{j@n(v1=6(SD?PJh1@q}^<u5cU=F3DLnfHzfMDWN^vY!yrnmFjKOzeySd^
z-)Rcvz2eCH+l#zzhqkK&n)@@eW4*$A=|3+H@OG3xwLDbLT_sCf9<?>)YaQn=e*Lzc
ze_>cGCmrywVxVQ$aSP|HeP_Geg^Bd3czH;N6lrtqDjmM0;aG2lLs(^?*!|%?uWp5O
zjY(3Eg{kjRi+m+`Yv}3WjV|n#7IrX{%81IOLn?b->v$S<DzjFcSoZ*Ecv8zvKe_x|
z+^WGG2)K=`{0{sn5AKj51%dGoBZ%W>X_wdl<B5BtUAt?@lLE>kKd=2Ps*Gen19NE#
zX=#5r_#Smcl~lyKUjH#17G+kaAKx&q{3P4&b=*Fzdd2x7DcWN><!`w48#t9^+k7Wr
zj}2}S-h5^Mx|)2!9aLMVszTNHz4=!j)hbepuCI5R#|6IpLKz@IAckeyZvj4}HL;cJ
zJGNE3L}*E&oSBC5+ucts_#$pAZ_Yj{w+Tcl_<zj@dUR#m+f9tZXH>>*13oG;!zYB8
ziF_ORx|N@kh=IBGT1{T1jKCOX9b9&8f@{sC?N(#yerQ<*2U+on9wYt%nt>59<~ed>
zOTqE6u)s*p+n-m?lVjV@5ZfC-{m2e=W0Lhm{lvI(*br0>hPI_hn_w1NSvDSV=Ff8Z
zx}~igI5i~vXFwgQhe-xz-gf@{0sFjia#55GC<;dh{|RQP*=e}o`6$6G_8T1Me7zNo
za)6>IR)?N_01DVIiHXN0xfe11%<$6`{m%K8eBmhOl#ICH+DdCfMI2SX3C(i}jCk_S
zvRUB*4N^b(Y05$FRH=h)+JzY&D9L9$ZaPjT=UMfR7|d&*eAB1#dEJQ<9Z!gPqE$_~
zy|z9O<y4vbu2)%x078CpnO$r8Vk~@Fh>UQJxML4ITb{}T#<B`4b?TQZ4LNlkMacqR
zTd#peK}*0W&$F$!`t5|xuD>1#Z%5|Xx{3CGsYKW+A%v^=k+1I1<K4fav#)_ADAH16
zS%2Z#z`Ngb_<hVSGrWwVZ*)-HXw+iIgw=|VlMy~a5(&Qa^L~#kx!+?X8EscNwe%gw
z%zmDH@HF``W`S+d_{wJYvw%Xs^Q6065IA|lXr8}{jzn-(o}vwI9^BK*o@RrhwJ6eD
zl<o|*|4vT%2D<LELEyR98_vc-h9Is}X<3-TiWrmID4`m>76>khj$}mF<pMuEFbe8?
z1iZ|+Tx7<<{(4Bh7yLp`I;2v0*Sj5J{kP~895?yVa{>c=X3t;&M*|crBxWCOFD{`L
z^wZdLrAsBRF^<yyPUQG%1_Z!g5w?F*7l-RyJsggULW1kGl0t(a$WQums_n$&S4MQA
zNFEoC%UDWxc<q!#+pk1qm;RNK57RM@)huBJb|%kNU$LR#10EkJUXRGzsv+Fr!-+rS
zFnXaD1;F7onmV(R=D1iHdEc6fRuD(1`pz{b!)|WfybR3uJcl@0$gZowi4MD9gcR*T
z9y_;H<`A$?jW6aCl;^~WZTP{WjVu`Pw#WWm%g(%3@2_Jg8X58D(UC&v0FXrjOq6{6
zxaqo|EHi0rUw<8#7iP~NR_5#zRp-RW?><O#Q1n$?{xf?KA%8w@{p@Q(NAwAYYzklC
zge!lUsO(2#^dc<Yg%X$^Y2|N6oid&So`VL38C1nBarKPY55R!N@lOecCw%zUmzapY
zxzAOP7Zz=CN5D~Ke0u<Yo54(NG#6=yrZVE6_9eLnoK=>nA+RWY=fT08l^?k!T2juF
z-+hwyPKZeKlVG~ZP$Y?gqU}RrIGuen+zU7cg0{!Oa4_$R@_loP4EZBH91;_p4>@Z|
zVI_ZLghSvncb#_%L(MR(YSibSbIb}uSZB%^1Ja<^O@O1?O%C|oo>`D==ANi&dbZ2Y
z##04m-9Kr51)mFnaFJO^@}Hs;A|NN*WKF=z&_OV2&>m=byr3PXU@+8)g(OLdrf^^`
z`{JNAw?z0cIt(a!JbykJ0b|eB6vyZ=1OI|Pm9dyp;vh<3Vw;ycFj(F(p&2g@*v?-K
zP@X{JuoS+dQ4NJX9*yEcKZg|A-rffgIObECzx3n{aAT(aD&4(5btB~@jX{LylrIGN
z`68Lqobnp7z=2||j8wD|YtzPD`NNF71wIWOq(>Flx1{_&hiEf00nb4PL8y8AWF>NX
z$Jdv@L+}X`k@u^lBA1jt(YK%vLkz%!a=H|Il#}z4ApSxIIvQ$%3xz#5C<jJ8z8q=!
z5FxmHe>rL5@#xdlzCVdS{Jsu}z}9qd;&^BGZGxCEza9e#4tl>{cFGN41-8S2P0)pZ
z(?GM}nyzxv)lOovmEsCMT(Q2x7Wk2li4~ZT6uiuDvp%7-$PifcTAVx|BF*l=APt6Z
ekh^;}kKOr$SW81~4}qV8f%J5Yu9sZHg#90d!)@vS

literal 0
HcmV?d00001

diff --git a/src/webui/service/templates/base.html b/src/webui/service/templates/base.html
index fcc8c0a8d..d5f748eae 100644
--- a/src/webui/service/templates/base.html
+++ b/src/webui/service/templates/base.html
@@ -38,7 +38,7 @@
 
     <nav class="navbar navbar-expand-lg navbar-dark bg-primary" style="margin-bottom: 10px;">
         <div class="container-fluid">
-          <a class="navbar-brand" href="#">
+          <a class="navbar-brand" href="{{ url_for('main.home') }}">
             <img src="https://teraflow-h2020.eu/sites/teraflow/files/public/favicon.png" alt="" width="30" height="24" class="d-inline-block align-text-top"/>
             TeraFlow
           </a>
@@ -55,25 +55,31 @@
                 {% endif %}
               </li>
               <li class="nav-item">
-                {% if '/service/' in request.path %}
-                <a class="nav-link active" aria-current="page" href="{{ url_for('service.home') }}">Service</a>
+                {% if '/device/' in request.path %}
+                <a class="nav-link active" aria-current="page" href="{{ url_for('device.home') }}">Device</a>
                 {% else %}
-                <a class="nav-link" href="{{ url_for('service.home') }}">Service</a>
+                <a class="nav-link" href="{{ url_for('device.home') }}">Device</a>
                 {% endif %}
-                <!-- <a class="nav-link" href="{{ url_for('service.home') }}">Service</a> -->
               </li>
               <li class="nav-item">
-                {% if '/device/' in request.path %}
-                <a class="nav-link active" aria-current="page" href="{{ url_for('device.home') }}">Device</a>
+                {% if '/link/' in request.path %}
+                <a class="nav-link active" aria-current="page" href="{{ url_for('link.home') }}">Link</a>
                 {% else %}
-                <a class="nav-link" href="{{ url_for('device.home') }}">Device</a>
+                <a class="nav-link" href="{{ url_for('link.home') }}">Link</a>
                 {% endif %}
-                <!-- <a class="nav-link" href="{{ url_for('service.home') }}">Service</a> -->
               </li>
-              <!-- <li class="nav-item">
-                <a class="nav-link" href="#">Compute</a>
+              <li class="nav-item">
+                {% if '/service/' in request.path %}
+                <a class="nav-link active" aria-current="page" href="{{ url_for('service.home') }}">Service</a>
+                {% else %}
+                <a class="nav-link" href="{{ url_for('service.home') }}">Service</a>
+                {% endif %}
               </li>
+              
               <li class="nav-item">
+                <a class="nav-link" href="#" id="grafana_link" target="grafana">Grafana</a>
+              </li>
+              <!-- <li class="nav-item">
                 <a class="nav-link" href="#">Context</a>
               </li>
               
@@ -110,14 +116,24 @@
         <div class="row">
           <div class="col-xxl-12">
           {% block content %}{% endblock %}
-        </div>
+          </div>
         </div>
       </main>
 
-      <footer class="footer" style="background-color: darkgrey;">
-        <div class="row">
-          <div class="col-md-12">
-            <p class="text-muted text-center" style="color: white;">&copy; 2021-2023</p>
+      <footer class="footer" style="background-color: darkgrey; margin-top: 30px; padding-top: 20px;">
+        <div class="container">
+          <div class="row">
+            <div class="col-md-12">
+              <p class="text-center" style="color: white;">&copy; 2021-2023</p>
+            </div>
+          </div>
+          <div class="row">
+            <div class="col-md-6">
+              <p>This project has received funding from the European Union's Horizon 2020 research and innovation programme under grant agreement No 101015857.</p>
+            </div>
+            <div class="col-md-6">
+              <img src="https://teraflow-h2020.eu/sites/teraflow/files/public/content-images/media/2021/logo%205G-ppp%20eu.png" width="310" alt="5g ppp EU logo" loading="lazy" typeof="foaf:Image">
+            </div>
           </div>
         </div>
       </footer>
@@ -127,7 +143,9 @@
     <!-- Option 1: Bootstrap Bundle with Popper -->
     <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-kQtW33rZJAHjgefvhyyzcGF3C5TFyBQBA13V1RKPf4uH+bwyzQxZ6CmMZHmNBEfJ" crossorigin="anonymous"></script>
     <!-- <script src="{{ url_for('static', filename='site.js') }}"/> -->
-
+    <script>
+      document.getElementById("grafana_link").href = window.location.protocol + "//" + window.location.hostname + ":30300"
+    </script>
     <!-- Option 2: Separate Popper and Bootstrap JS -->
     <!--
     <script src="https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js" integrity="sha384-7+zCNj/IqJ95wo16oMtfsKbZ9ccEh31eOz1HGyDuCQ6wgnyJNSYdrPa03rtR1zdB" crossorigin="anonymous"></script>
diff --git a/src/webui/service/templates/device/add.html b/src/webui/service/templates/device/add.html
index aada90f38..fe1ba31f2 100644
--- a/src/webui/service/templates/device/add.html
+++ b/src/webui/service/templates/device/add.html
@@ -101,9 +101,16 @@
                     List the device drivers by their numerical ID, separated by commas, without spaces between them. Numerical IDs: {{ device_driver_ids }}.
                 </div>
             </div>
-            <div class="row mb-3">
-                <button type="submit" class="btn btn-primary">{{ submit_text }}</button>
-            </div>
+            <div class="d-grid gap-2 d-md-flex justify-content-md-start">
+                <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/device/detail.html b/src/webui/service/templates/device/detail.html
index a8c635808..143bbeed7 100644
--- a/src/webui/service/templates/device/detail.html
+++ b/src/webui/service/templates/device/detail.html
@@ -21,10 +21,16 @@
 
     <div class="row mb-3">
         <div class="col-sm-3">
-            <button type="button" class="btn btn-success" onclick="window.location.href = '/device/'"><i class="bi bi-box-arrow-in-left"></i>Back to device list</button>
+            <button type="button" class="btn btn-success" onclick="window.location.href = '/device/'">
+                <i class="bi bi-box-arrow-in-left"></i>
+                Back to device 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>
+            <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 device</button> -->
@@ -35,24 +41,22 @@
     </div>
 
     <div class="row mb-3">
-        <b>UUID:</b>
-        <div class="col-sm-10">
+        <div class="col-sm-1"><b>UUID:</b></div>
+        <div class="col-sm-5">
             {{ device.device_id.device_uuid.uuid }}
         </div>
-    </div>
-    <div class="row mb-3">
-        <b>Type:</b>
-        <div class="col-sm-10">
+        <div class="col-sm-1"><b>Type:</b></div>
+        <div class="col-sm-5">
             {{ device.device_type }}
         </div>
     </div>
     <div class="row mb-3">
-        <b>Configurations:</b>
-        <div class="col-sm-10">
+        <div class="col-sm-1"><b>Drivers:</b></div>
+        <div class="col-sm-11">
             <ul>
-            {% for config in device.device_config.config_rules %}
-                <li>{{ config.resource_key }}: {{ config.resource_value }}</li>
-            {% endfor %}
+                {% for driver in device.device_drivers %}
+                <li>{{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}</li>
+                {% endfor %}
             </ul>
         </div>
     </div>
@@ -66,6 +70,22 @@
             </ul>
         </div>
     </div>
+    <div class="row mb-3">
+        <b>Configurations:</b>
+        <div class="col-sm-10">
+            <ul>
+            {% for config in device.device_config.config_rules %}
+                <li>{{ config.resource_key }}:
+                    <ul>
+                        {% for key, value in (config.resource_value | from_json).items() %}
+                        <li><b>{{ key }}:</b> {{ value }}</li>
+                        {% endfor %}
+                    </ul>
+                </li>
+            {% endfor %}
+            </ul>
+        </div>
+    </div>
 
     <!-- Modal -->
 <div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
diff --git a/src/webui/service/templates/device/home.html b/src/webui/service/templates/device/home.html
index 9f3190669..2c108add9 100644
--- a/src/webui/service/templates/device/home.html
+++ b/src/webui/service/templates/device/home.html
@@ -47,7 +47,7 @@
             <th scope="col">Endpoints</th>
             <th scope="col">Drivers</th>
             <th scope="col">Status</th>
-            <th scope="col">Configuration</th>
+            <!-- <th scope="col">Configuration</th> -->
             <th scope="col"></th>
           </tr>
         </thead>
@@ -73,12 +73,12 @@
                     <td>
                         <ul>
                             {% for driver in device.device_drivers %}
-                            <li>{{ dde.Name(driver).replace('DEVICEDRIVER_', '') }}</li>
+                            <li>{{ dde.Name(driver).replace('DEVICEDRIVER_', '').replace('UNDEFINED', 'EMULATED') }}</li>
                             {% endfor %}
                         </ul>
                     </td>
                     <td>{{ dose.Name(device.device_operational_status).replace('DEVICEOPERATIONALSTATUS_', '') }}</td>
-                    <td>
+                    <!-- <td>
                         <ul>
                             {% for config in device.device_config.config_rules %}
                             <li>
@@ -87,7 +87,7 @@
                             </li>
                             {% endfor %}
                         </ul>
-                    </td>
+                    </td> -->
                     <td>
                         <a href="{{ url_for('device.detail', device_uuid=device.device_id.device_uuid.uuid) }}">
                             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
diff --git a/src/webui/service/templates/link/home.html b/src/webui/service/templates/link/home.html
new file mode 100644
index 000000000..d0c122f6a
--- /dev/null
+++ b/src/webui/service/templates/link/home.html
@@ -0,0 +1,96 @@
+<!--
+ Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+{% extends 'base.html' %}
+
+{% block content %}
+    <h1>Links</h1>
+
+    <div class="row">
+        <div class="col">
+            <!-- <a href="#" class="btn btn-primary" style="margin-bottom: 10px;">
+                <i class="bi bi-plus"></i>
+                Add New Link
+            </a> -->
+        </div>
+        <div class="col">
+            {{ links | length }} links found</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>
+            <th scope="col">#</th>
+            <th scope="col">Endpoints</th>
+            <th scope="col"></th>
+          </tr>
+        </thead>
+        <tbody>
+            {% if links %}
+                {% for link in links %}
+                <tr>
+                    <td>
+                        <!-- <a href="#"> -->
+                            {{ link.link_id.link_uuid.uuid }}
+                        <!-- </a> -->
+                    </td>
+
+                    <td>
+                        <ul>
+                            {% for end_point in link.link_endpoint_ids %}
+                            <li>
+                                {{ end_point.endpoint_uuid.uuid }} / 
+                                Device: 
+                                <a href="{{ url_for('device.detail', device_uuid=end_point.device_id.device_uuid.uuid) }}">
+                                    {{ end_point.device_id.device_uuid.uuid }}
+                                    <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
+                                        <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
+                                        <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
+                                    </svg>
+                                </a>
+                            </li>
+                            {% endfor %}
+                        </ul>
+                    </td>
+
+                    <td>
+                        <!-- <a href="#">
+                            <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
+                                <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
+                                <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
+                            </svg>
+                        </a> -->
+                    </td>
+                </tr>
+                {% endfor %}
+            {% else %}
+                <tr>
+                    <td colspan="7">No links found</td>
+                </tr>
+            {% endif %}
+        </tbody>
+    </table>
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/webui/service/templates/main/about.html b/src/webui/service/templates/main/about.html
index 8bb77b63e..4ba3a5845 100644
--- a/src/webui/service/templates/main/about.html
+++ b/src/webui/service/templates/main/about.html
@@ -20,6 +20,6 @@
 
     <p>For more information, visit the <a href="https://teraflow-h2020.eu/" target="_newtf">TeraFlow H2020 webpage</a>.</p>
 
-    <img alt="Consortium" src="{{ url_for('static', filename='partners.png') }}"/>
+    <img alt="Consortium" class="img-fluid" src="{{ url_for('static', filename='partners.png') }}"/>
 
 {% endblock %}
\ No newline at end of file
diff --git a/src/webui/service/templates/main/home.html b/src/webui/service/templates/main/home.html
index e7633bbdb..2134a3a87 100644
--- a/src/webui/service/templates/main/home.html
+++ b/src/webui/service/templates/main/home.html
@@ -17,8 +17,7 @@
 {% extends 'base.html' %}
 
 {% block content %}
-    <h1>This is the home page</h1>
-    <p>Here we have have several things.</p>
+    <h1>TeraFlow OS SDN Controller</h1>
 
     {% for field, message in context_form.errors.items() %}
         <div class="alert alert-dismissible fade show" role="alert">
@@ -28,26 +27,58 @@
 
     {% endfor %}
 
-    <h2>Select the working context</h2>
-    <form id="select_context" method="POST">
+    <form id="select_context" method="POST" enctype="multipart/form-data">
         {{ context_form.hidden_tag() }}
         <fieldset class="form-group">
-            <div class="input-group mb-3">
-
-                {% if context_form.context.errors %}
-                    {{ context_form.context(class="form-select is-invalid") }}
-                    <div class="invalid-feedback">
-                        {% for error in context_form.context.errors %}
-                            <span>{{ error }}</span>
-                        {% endfor %}
-                    </div>
-                {% else %}
-                    {{ context_form.context(class="form-select") }}
-                {% endif %}
-
-                {{ context_form.submit(class='btn btn-primary') }}
+            <legend>Select the working context, or upload a JSON descriptors file</legend>
+            <div class="row mb-3">
+                {{ context_form.context.label(class="col-sm-1 col-form-label") }}
+                <div class="col-sm-5">
+                    {% if context_form.context.errors %}
+                        {{ context_form.context(class="form-select is-invalid") }}
+                        <div class="invalid-feedback">
+                            {% for error in context_form.context.errors %}
+                                <span>{{ error }}</span>
+                            {% endfor %}
+                        </div>
+                    {% else %}
+                        {{ context_form.context(class="form-select") }}
+                    {% endif %}
+                </div>
+                <div class="col-sm-2">
+                    {{ context_form.submit(class='btn btn-primary') }}
+                </div>
             </div>
         </fieldset>
     </form>
 
-{% endblock %}
\ No newline at end of file
+    <form id="select_context" method="POST" enctype="multipart/form-data">
+        {{ context_form.hidden_tag() }}
+        <fieldset class="form-group">
+            <legend>Upload a JSON descriptors file</legend>
+            <div class="row mb-3">
+                {{ descriptor_form.descriptors.label(class="col-sm-1 col-form-label") }}
+                <div class="col-sm-5">
+                    {% if descriptor_form.descriptors.errors %}
+                        {{ descriptor_form.descriptors(class="form-control is-invalid") }}
+                        <div class="invalid-feedback">
+                            {% for error in descriptor_form.descriptors.errors %}
+                                <span>{{ error }}</span>
+                            {% endfor %}
+                        </div>
+                    {% else %}
+                        {{ descriptor_form.descriptors(class="form-control") }}
+                    {% endif %}
+                </div>
+                <div class="col-sm-2">
+                    {{ descriptor_form.submit(class='btn btn-primary') }}
+                </div>
+            </div>
+        </fieldset>
+    </form>
+
+    <script src="https://d3js.org/d3.v4.min.js"></script>
+    <div id="topology"></div>
+    <script src="{{ url_for('static', filename='topology.js') }}"></script>
+
+{% endblock %}
diff --git a/src/webui/service/templates/service/detail.html b/src/webui/service/templates/service/detail.html
new file mode 100644
index 000000000..77988c74c
--- /dev/null
+++ b/src/webui/service/templates/service/detail.html
@@ -0,0 +1,99 @@
+<!--
+ Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+{% extends 'base.html' %}
+
+{% block content %}
+    <h1>Service {{ service.service_id.service_uuid.uuid }}</h1>
+
+    <div class="row mb-3">
+        <div class="col-sm-3">
+            <button type="button" class="btn btn-success" onclick="window.location.href = '/service/'">
+                <i class="bi bi-box-arrow-in-left"></i>
+                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
+              </button>
+        </div>
+    </div>
+
+    <div class="row mb-3">
+        <div class="col-sm-1"><b>UUID:</b></div>
+        <div class="col-sm-5">
+            {{ service.service_id.service_uuid.uuid }}
+        </div>
+        <div class="col-sm-1"><b>Type:</b></div>
+        <div class="col-sm-5">
+            {{ service.service_type }}
+        </div>
+    </div>
+    <div class="row mb-3">
+        <b>Endpoints:</b>
+        <div class="col-sm-10">
+            <ul>
+            {% for endpoint in service.service_endpoint_ids %}
+                <li>{{ endpoint.endpoint_uuid.uuid }}: {{ endpoint.endpoint_type }}</li>
+            {% endfor %}
+            </ul>
+        </div>
+    </div>
+    <div class="row mb-3">
+        <b>Configurations:</b>
+        <div class="col-sm-10">
+            <ul>
+            {% for config in service.service_config.config_rules %}
+                <li>{{ config.resource_key }}:
+                    <ul>
+                        {% for key, value in (config.resource_value | from_json).items() %}
+                        <li><b>{{ key }}:</b> {{ value }}</li>
+                        {% endfor %}
+                    </ul>
+                </li>
+            {% endfor %}
+            </ul>
+        </div>
+    </div>
+
+    <!-- Modal -->
+<div class="modal fade" id="deleteModal" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
+    <div class="modal-dialog">
+      <div class="modal-content">
+        <div class="modal-header">
+          <h5 class="modal-title" id="staticBackdropLabel">Delete service?</h5>
+          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
+        </div>
+        <div class="modal-body">
+          Are you sure you want to delete the service "{{ service.service_id.service_uuid.uuid }}"?
+        </div>
+        <div class="modal-footer">
+          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">No</button>
+          <a type="button" class="btn btn-danger" href="{{ url_for('service.delete', service_uuid=service.service_id.service_uuid.uuid) }}"><i class="bi bi-exclamation-diamond"></i>Yes</a>
+        </div>
+      </div>
+    </div>
+  </div>
+
+{% endblock %}
\ No newline at end of file
diff --git a/src/webui/service/templates/service/home.html b/src/webui/service/templates/service/home.html
index 8f6a99dc3..0e152006c 100644
--- a/src/webui/service/templates/service/home.html
+++ b/src/webui/service/templates/service/home.html
@@ -20,7 +20,6 @@
     <h1>Services</h1>
 
     <div class="row">
-        {% if context_found %}
         <!-- <div class="col">
             <a href="{{ url_for('service.add') }}" class="btn btn-primary" style="margin-bottom: 10px;">
                 <i class="bi bi-plus"></i>
@@ -38,11 +37,6 @@
                   </div>
             </form>
         </div> -->
-        {% else %}
-        <div class="col">
-            Context <i>{{ session['context_uuid'] }}</i> not found.
-        </div>
-        {% endif %}
     </div>
     
 
@@ -54,8 +48,7 @@
             <th scope="col">End points</th>
             <th scope="col">Constraints</th>
             <th scope="col">Status</th>
-            <th scope="col">Configuration</th>
-            <!-- <th scope="col"></th> -->
+            <th scope="col"></th>
           </tr>
         </thead>
         <tbody>
@@ -86,24 +79,13 @@
                     </td>
                     <td>{{ sse.Name(service.service_status.service_status).replace('SERVICESTATUS_', '') }}</td>
                     <td>
-                        <ul>
-                            {% for rule in service.service_config.config_rules %}
-                            <li>
-                                Key: {{ rule.resource_key }}
-                                <br/>
-                                Value: {{ rule.resource_value }}
-                            </li>
-                            {% endfor %}
-                        </ul>
-                    </td>
-                    <!-- <td>
-                        <a href="{{ url_for('service.detail', service_uuid=service.service_id.service_uuid.uuid.replace('/', '_')) }}">
+                        <a href="{{ url_for('service.detail', service_uuid=service.service_id.service_uuid.uuid) }}">
                             <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-eye" viewBox="0 0 16 16">
                                 <path d="M16 8s-3-5.5-8-5.5S0 8 0 8s3 5.5 8 5.5S16 8 16 8zM1.173 8a13.133 13.133 0 0 1 1.66-2.043C4.12 4.668 5.88 3.5 8 3.5c2.12 0 3.879 1.168 5.168 2.457A13.133 13.133 0 0 1 14.828 8c-.058.087-.122.183-.195.288-.335.48-.83 1.12-1.465 1.755C11.879 11.332 10.119 12.5 8 12.5c-2.12 0-3.879-1.168-5.168-2.457A13.134 13.134 0 0 1 1.172 8z"/>
                                 <path d="M8 5.5a2.5 2.5 0 1 0 0 5 2.5 2.5 0 0 0 0-5zM4.5 8a3.5 3.5 0 1 1 7 0 3.5 3.5 0 0 1-7 0z"/>
                             </svg>
                         </a>
-                    </td> -->
+                    </td>
                 </tr>
                 {% endfor %}
             {% else %}
-- 
GitLab


From 86c990194ae33efa09873b75a4843097b9a0e529 Mon Sep 17 00:00:00 2001
From: Georgios Katsikas <katsikas.gp@gmail.com>
Date: Wed, 9 Mar 2022 12:16:07 +0200
Subject: [PATCH 02/60] fix: broken P4 tests

Signed-off-by: Georgios Katsikas <katsikas.gp@gmail.com>
---
 src/device/service/drivers/p4/p4_driver.py |  2 +-
 src/device/tests/device_p4.py              | 30 ++++++++++++----------
 src/device/tests/test_unit_p4.py           |  4 +--
 src/device/tests/test_unitary.py           | 29 ++++++++++++++-------
 4 files changed, 39 insertions(+), 26 deletions(-)

diff --git a/src/device/service/drivers/p4/p4_driver.py b/src/device/service/drivers/p4/p4_driver.py
index 3e0cccffa..af05952b3 100644
--- a/src/device/service/drivers/p4/p4_driver.py
+++ b/src/device/service/drivers/p4/p4_driver.py
@@ -44,7 +44,7 @@ class P4Driver(_Driver):
         transport port number of the P4Runtime server running on the P4 device
     **settings : map
         id : int
-            P4 device ID (Mandatory)
+            P4 device datapath ID (Mandatory)
         name : str
             P4 device name (Optional)
         vendor : str
diff --git a/src/device/tests/device_p4.py b/src/device/tests/device_p4.py
index 577855dd4..4cd0a4c74 100644
--- a/src/device/tests/device_p4.py
+++ b/src/device/tests/device_p4.py
@@ -17,9 +17,10 @@ P4 device example configuration.
 """
 
 from common.tools.object_factory.ConfigRule import json_config_rule_set
-from common.tools.object_factory.Device import json_device_p4_disabled
+from common.tools.object_factory.Device import (
+    json_device_connect_rules, json_device_id, json_device_p4_disabled)
 
-DEVICE_P4_ID = 0
+DEVICE_P4_DPID = 0
 DEVICE_P4_NAME = 'device:leaf1'
 DEVICE_P4_ADDRESS = '127.0.0.1'
 DEVICE_P4_PORT = '50101'
@@ -29,21 +30,22 @@ DEVICE_P4_SW_VER = 'Stratum'
 DEVICE_P4_PIPECONF = 'org.onosproject.pipelines.fabric'
 DEVICE_P4_WORKERS = 2
 DEVICE_P4_GRACE_PERIOD = 60
+DEVICE_P4_TIMEOUT = 60
 
-DEVICE_P4_UUID = {'device_uuid': {'uuid': DEVICE_P4_NAME}}
+DEVICE_P4_UUID = DEVICE_P4_NAME
+DEVICE_P4_ID = json_device_id(DEVICE_P4_UUID)
 DEVICE_P4 = json_device_p4_disabled(DEVICE_P4_UUID)
 
-DEVICE_P4_CONNECT_RULES = [
-    json_config_rule_set('_connect/address', DEVICE_P4_ADDRESS),
-    json_config_rule_set('_connect/port', DEVICE_P4_PORT),
-    json_config_rule_set('_connect/settings', {
-        'id'      : int(DEVICE_P4_ID),
-        'name'    : DEVICE_P4_NAME,
-        'hw-ver'  : DEVICE_P4_HW_VER,
-        'sw-ver'  : DEVICE_P4_SW_VER,
-        'pipeconf': DEVICE_P4_PIPECONF
-    }),
-]
+DEVICE_P4_CONNECT_RULES = json_device_connect_rules(
+    DEVICE_P4_ADDRESS, DEVICE_P4_PORT, {
+        'id': DEVICE_P4_DPID,
+        'name': DEVICE_P4_NAME,
+        'hw-ver': DEVICE_P4_HW_VER,
+        'sw-ver': DEVICE_P4_SW_VER,
+        'pipeconf': DEVICE_P4_PIPECONF,
+        'timeout': DEVICE_P4_TIMEOUT
+    }
+)
 
 DEVICE_P4_CONFIG_RULES = [
     json_config_rule_set('key1', 'value1'),
diff --git a/src/device/tests/test_unit_p4.py b/src/device/tests/test_unit_p4.py
index 853d9d8a5..777ab280a 100644
--- a/src/device/tests/test_unit_p4.py
+++ b/src/device/tests/test_unit_p4.py
@@ -15,7 +15,7 @@
 import pytest
 from device.service.drivers.p4.p4_driver import P4Driver
 from .device_p4 import(
-        DEVICE_P4_ADDRESS, DEVICE_P4_PORT, DEVICE_P4_ID, DEVICE_P4_NAME,
+        DEVICE_P4_ADDRESS, DEVICE_P4_PORT, DEVICE_P4_DPID, DEVICE_P4_NAME,
         DEVICE_P4_VENDOR, DEVICE_P4_HW_VER, DEVICE_P4_SW_VER,
         DEVICE_P4_PIPECONF, DEVICE_P4_WORKERS, DEVICE_P4_GRACE_PERIOD)
 from .mock_p4runtime_service import MockP4RuntimeService
@@ -37,7 +37,7 @@ def device_driverapi_p4():
     _driver = P4Driver(
         address=DEVICE_P4_ADDRESS,
         port=DEVICE_P4_PORT,
-        id=DEVICE_P4_ID,
+        id=DEVICE_P4_DPID,
         name=DEVICE_P4_NAME,
         vendor=DEVICE_P4_VENDOR,
         hw_ver=DEVICE_P4_HW_VER,
diff --git a/src/device/tests/test_unitary.py b/src/device/tests/test_unitary.py
index 64c54deb0..411cbba05 100644
--- a/src/device/tests/test_unitary.py
+++ b/src/device/tests/test_unitary.py
@@ -81,7 +81,7 @@ except ImportError:
 #ENABLE_EMULATED   = False # set to False to disable tests of Emulated devices
 #ENABLE_OPENCONFIG = False # set to False to disable tests of OpenConfig devices
 #ENABLE_TAPI       = False # set to False to disable tests of TAPI devices
-ENABLE_P4         = False # set to False to disable tests of P4 devices (P4 device not available in GitLab)
+#ENABLE_P4         = False # set to False to disable tests of P4 devices
 
 ENABLE_OPENCONFIG_CONFIGURE   = True
 ENABLE_OPENCONFIG_MONITOR     = True
@@ -917,7 +917,8 @@ def test_device_p4_add_error_cases(
         device_client: DeviceClient,     # pylint: disable=redefined-outer-name
         device_service: DeviceService):  # pylint: disable=redefined-outer-name
 
-    if not ENABLE_P4: pytest.skip('Skipping test: No P4 device has been configured')
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
 
     with pytest.raises(grpc.RpcError) as e:
         device_p4_with_extra_rules = copy.deepcopy(DEVICE_P4)
@@ -940,13 +941,14 @@ def test_device_p4_add_correct(
         device_service: DeviceService,              # pylint: disable=redefined-outer-name
         p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
 
-    if not ENABLE_P4: pytest.skip('Skipping test: No P4 device has been configured')
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
 
     device_p4_with_connect_rules = copy.deepcopy(DEVICE_P4)
     device_p4_with_connect_rules['device_config']['config_rules'].extend(
         DEVICE_P4_CONNECT_RULES)
     device_client.AddDevice(Device(**device_p4_with_connect_rules))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_P4_NAME)
+    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_P4_UUID)
     assert driver is not None
 
 
@@ -956,13 +958,14 @@ def test_device_p4_get(
         device_service: DeviceService,              # pylint: disable=redefined-outer-name
         p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
 
-    if not ENABLE_P4: pytest.skip('Skipping test: No P4 device has been configured')
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
 
-    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_P4_UUID))
+    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_P4_ID))
     LOGGER.info('initial_config = {:s}'.format(
         grpc_message_to_json_string(initial_config)))
 
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_P4_UUID))
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_P4_ID))
     LOGGER.info('device_data = {:s}'.format(
         grpc_message_to_json_string(device_data)))
 
@@ -972,6 +975,10 @@ def test_device_p4_configure(
         device_client: DeviceClient,                # pylint: disable=redefined-outer-name
         device_service: DeviceService,              # pylint: disable=redefined-outer-name
         p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
+
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
+
     pytest.skip('Skipping test for unimplemented method')
 
 
@@ -980,6 +987,10 @@ def test_device_p4_deconfigure(
         device_client: DeviceClient,                # pylint: disable=redefined-outer-name
         device_service: DeviceService,              # pylint: disable=redefined-outer-name
         p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
+
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
+
     pytest.skip('Skipping test for unimplemented method')
 
 
@@ -991,6 +1002,6 @@ def test_device_p4_delete(
 
     if not ENABLE_P4: pytest.skip('Skipping test: No P4 device has been configured')
 
-    device_client.DeleteDevice(DeviceId(**DEVICE_P4_UUID))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_P4_NAME)
+    device_client.DeleteDevice(DeviceId(**DEVICE_P4_ID))
+    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_P4_UUID)
     assert driver is None
-- 
GitLab


From 5423d16cfa8931c71d055f9e33c8ee53d67addac Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Tue, 3 May 2022 12:16:29 +0000
Subject: [PATCH 03/60] Initial functional versions of Interdomain and Slice
 components

---
 .gitlab-ci.yml                                |   22 +-
 deploy_in_kubernetes.sh                       |    9 +-
 manifests/interdomainservice.yaml             |   64 +
 manifests/sliceservice.yaml                   |   64 +
 manifests/webuiservice.yaml                   |    8 +-
 oeccpsc22                                     |    1 +
 proto/context.proto                           |   46 +
 proto/interdomain.proto                       |   18 +-
 proto/slice.proto                             |   36 +-
 report_coverage_slice.sh                      |    3 +
 scripts/run_tests_locally-slice.sh            |   28 +
 scripts/run_tests_locally.sh                  |    3 +
 .../database/api/context/slice/SliceStatus.py |   31 +
 .../database/api/context/slice/__init__.py    |    0
 src/common/logger.py                          |    2 +-
 src/common/rpc_method_wrapper/Decorator.py    |    5 +-
 src/common/tests/MockServicerImpl_Slice.py    |   45 +
 src/common/tools/client/RetryDecorator.py     |    2 +-
 src/common/tools/grpc/Tools.py                |    5 +-
 src/compute/Dockerfile                        |    1 +
 src/compute/genproto.sh                       |   21 +-
 src/compute/proto/context_pb2.py              |  495 ++-
 src/compute/proto/service_pb2.py              |   14 +-
 .../nbi_plugins/ietf_l2vpn/Constants.py       |   26 +
 .../nbi_plugins/ietf_l2vpn/L2VPN_Service.py   |   36 +-
 .../nbi_plugins/ietf_l2vpn/L2VPN_Services.py  |   36 +-
 .../ietf_l2vpn/L2VPN_SiteNetworkAccesses.py   |   67 +-
 .../ietf_l2vpn/schemas/vpn_service.py         |    2 +-
 .../ietf_l2vpn/tools/ContextMethods.py        |   39 +
 .../tests/mock_osm/WimconnectorIETFL2VPN.py   |  315 +-
 src/compute/tests/test_unitary.py             |    6 +
 src/context/client/ContextClient.py           |  191 +-
 src/context/client/EventsCollector.py         |    5 +
 src/context/genproto.sh                       |   21 +-
 src/context/proto/context_pb2.py              |  495 ++-
 src/context/proto/context_pb2_grpc.py         |  198 ++
 .../service/database/RelationModels.py        |   16 +
 src/context/service/database/SliceModel.py    |   85 +
 src/context/service/grpc_server/Constants.py  |    5 +-
 .../grpc_server/ContextServiceServicerImpl.py |  161 +-
 src/context/service/rest_server/Resources.py  |   26 +-
 src/dbscanserving/genproto.sh                 |   21 +-
 src/dbscanserving/proto/dbscanserving_pb2.py  |   24 +-
 src/device/genproto.sh                        |   21 +-
 src/device/proto/context_pb2.py               |  495 ++-
 src/interdomain/.gitlab-ci.yml                |  102 +
 src/interdomain/Config.py                     |   33 +
 src/interdomain/Dockerfile                    |   54 +
 src/interdomain/__init__.py                   |   14 +
 src/interdomain/client/InterdomainClient.py   |   77 +
 src/interdomain/client/__init__.py            |   14 +
 src/interdomain/genproto.sh                   |   52 +
 src/interdomain/proto/__init__.py             |   14 +
 src/interdomain/proto/context_pb2.py          | 3071 +++++++++++++++++
 src/interdomain/proto/interdomain_pb2.py      |   98 +
 src/interdomain/proto/interdomain_pb2_grpc.py |  198 ++
 src/interdomain/proto/kpi_sample_types_pb2.py |   78 +
 src/interdomain/proto/slice_pb2.py            |   78 +
 src/interdomain/requirements.in               |    6 +
 src/interdomain/service/InterdomainService.py |   76 +
 .../service/InterdomainServiceServicerImpl.py |  152 +
 .../service/RemoteDomainClients.py            |   56 +
 src/interdomain/service/__init__.py           |   14 +
 src/interdomain/service/__main__.py           |   96 +
 src/interdomain/tests/__init__.py             |   14 +
 src/interdomain/tests/test_unitary.py         |  146 +
 src/l3_attackmitigator/genproto.sh            |   28 +-
 src/l3_attackmitigator/proto/context_pb2.py   | 3071 +++++++++++++++++
 .../proto/kpi_sample_types_pb2.py             |   78 +
 .../proto/l3_attackmitigator_pb2.py           |  132 +-
 .../proto/l3_attackmitigator_pb2_grpc.py      |   26 +-
 src/l3_centralizedattackdetector/genproto.sh  |   32 +-
 .../proto/context_pb2.py                      | 3071 +++++++++++++++++
 .../proto/kpi_sample_types_pb2.py             |   78 +
 .../proto/l3_attackmitigator_pb2.py           |  132 +-
 .../proto/l3_attackmitigator_pb2_grpc.py      |  102 -
 .../proto/l3_centralizedattackdetector_pb2.py |  154 +-
 .../l3_centralizedattackdetector_pb2_grpc.py  |   12 +-
 src/l3_distributedattackdetector/genproto.sh  |   21 +-
 .../proto/l3_centralizedattackdetector_pb2.py |  154 +-
 .../l3_centralizedattackdetector_pb2_grpc.py  |   12 +-
 src/monitoring/genproto.sh                    |   19 +-
 src/monitoring/proto/context_pb2.py           |  495 ++-
 src/monitoring/requirements.in                |   29 +-
 src/monitoring/tests/test_unitary.py          |   25 +-
 src/opticalattackmitigator/genproto.sh        |   21 +-
 .../proto/context_pb2.py                      |  495 ++-
 .../genproto.sh                               |   21 +-
 .../proto/context_pb2.py                      |  495 ++-
 .../proto/service_pb2.py                      |   14 +-
 src/service/client/ServiceClient.py           |   13 +-
 src/service/genproto.sh                       |   21 +-
 src/service/proto/context_pb2.py              |  495 ++-
 src/service/proto/service_pb2.py              |   14 +-
 src/service/proto/service_pb2_grpc.py         |   33 -
 .../service/ServiceServiceServicerImpl.py     |    2 +
 src/slice/.gitlab-ci.yml                      |   74 +
 src/slice/Config.py                           |   22 +
 src/slice/Dockerfile                          |   38 +
 src/slice/__init__.py                         |   14 +
 src/slice/client/SliceClient.py               |   63 +
 src/slice/client/__init__.py                  |   14 +
 src/slice/genproto.sh                         |   52 +
 src/slice/old_code/ConstraintsChecker.py      |   52 +
 src/slice/old_code/SliceCheckers.py           |   32 +
 src/slice/old_code/Tools.py                   |  213 ++
 src/slice/old_code/Tools_2.py                 |  190 +
 src/slice/proto/__init__.py                   |   14 +
 src/slice/proto/context_pb2.py                | 3071 +++++++++++++++++
 src/slice/proto/kpi_sample_types_pb2.py       |   78 +
 src/slice/proto/service_pb2.py                |   78 +
 src/slice/proto/slice_pb2.py                  |   78 +
 src/slice/proto/slice_pb2_grpc.py             |  132 +
 src/slice/requirements.in                     |    6 +
 src/slice/service/SliceService.py             |   76 +
 src/slice/service/SliceServiceServicerImpl.py |  134 +
 src/slice/service/__init__.py                 |   14 +
 src/slice/service/__main__.py                 |  101 +
 src/slice/tests/__init__.py                   |   14 +
 src/slice/tests/test_unitary.py               |   51 +
 src/tests/.gitlab-ci.yml                      |    3 +-
 src/tests/oeccpsc22/README.md                 |    8 +
 src/tests/oeccpsc22/__init__.py               |   14 +
 src/tests/oeccpsc22/deploy_in_kubernetes.sh   |  159 +
 src/tests/oeccpsc22/dump_logs.sh              |   32 +
 .../oeccpsc22/expose_services_teraflow_1.yaml |  106 +
 .../oeccpsc22/expose_services_teraflow_2.yaml |  106 +
 src/tests/oeccpsc22/run_test_01_bootstrap.sh  |   60 +
 .../run_test_02_create_interdomain_slice.sh   |   49 +
 .../run_test_03_delete_interdomain_slice.sh   |   49 +
 src/tests/oeccpsc22/run_test_04_cleanup.sh    |   49 +
 src/tests/oeccpsc22/show_deploy.sh            |   26 +
 src/tests/oeccpsc22/tests/.gitignore          |    2 +
 src/tests/oeccpsc22/tests/Objects_Domain_1.py |  133 +
 src/tests/oeccpsc22/tests/Objects_Domain_2.py |  133 +
 src/tests/oeccpsc22/tests/Objects_Service.py  |   37 +
 src/tests/oeccpsc22/tests/Tools.py            |   25 +
 src/tests/oeccpsc22/tests/__init__.py         |   14 +
 .../tests/test_functional_bootstrap.py        |  213 ++
 .../tests/test_functional_cleanup.py          |  123 +
 ...est_functional_create_interdomain_slice.py |  129 +
 ...est_functional_delete_interdomain_slice.py |  143 +
 src/webui/genproto.sh                         |   21 +-
 src/webui/proto/context_pb2.py                |  495 ++-
 src/webui/proto/service_pb2.py                |   14 +-
 145 files changed, 22303 insertions(+), 1403 deletions(-)
 create mode 100644 manifests/interdomainservice.yaml
 create mode 100644 manifests/sliceservice.yaml
 create mode 120000 oeccpsc22
 create mode 100755 report_coverage_slice.sh
 create mode 100755 scripts/run_tests_locally-slice.sh
 create mode 100644 src/common/database/api/context/slice/SliceStatus.py
 create mode 100644 src/common/database/api/context/slice/__init__.py
 create mode 100644 src/common/tests/MockServicerImpl_Slice.py
 create mode 100644 src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/ContextMethods.py
 create mode 100644 src/context/service/database/SliceModel.py
 create mode 100644 src/interdomain/.gitlab-ci.yml
 create mode 100644 src/interdomain/Config.py
 create mode 100644 src/interdomain/Dockerfile
 create mode 100644 src/interdomain/__init__.py
 create mode 100644 src/interdomain/client/InterdomainClient.py
 create mode 100644 src/interdomain/client/__init__.py
 create mode 100755 src/interdomain/genproto.sh
 create mode 100644 src/interdomain/proto/__init__.py
 create mode 100644 src/interdomain/proto/context_pb2.py
 create mode 100644 src/interdomain/proto/interdomain_pb2.py
 create mode 100644 src/interdomain/proto/interdomain_pb2_grpc.py
 create mode 100644 src/interdomain/proto/kpi_sample_types_pb2.py
 create mode 100644 src/interdomain/proto/slice_pb2.py
 create mode 100644 src/interdomain/requirements.in
 create mode 100644 src/interdomain/service/InterdomainService.py
 create mode 100644 src/interdomain/service/InterdomainServiceServicerImpl.py
 create mode 100644 src/interdomain/service/RemoteDomainClients.py
 create mode 100644 src/interdomain/service/__init__.py
 create mode 100644 src/interdomain/service/__main__.py
 create mode 100644 src/interdomain/tests/__init__.py
 create mode 100644 src/interdomain/tests/test_unitary.py
 mode change 100644 => 100755 src/l3_attackmitigator/genproto.sh
 create mode 100644 src/l3_attackmitigator/proto/context_pb2.py
 create mode 100644 src/l3_attackmitigator/proto/kpi_sample_types_pb2.py
 mode change 100644 => 100755 src/l3_centralizedattackdetector/genproto.sh
 create mode 100644 src/l3_centralizedattackdetector/proto/context_pb2.py
 create mode 100644 src/l3_centralizedattackdetector/proto/kpi_sample_types_pb2.py
 delete mode 100644 src/l3_centralizedattackdetector/proto/l3_attackmitigator_pb2_grpc.py
 mode change 100644 => 100755 src/l3_distributedattackdetector/genproto.sh
 create mode 100644 src/slice/.gitlab-ci.yml
 create mode 100644 src/slice/Config.py
 create mode 100644 src/slice/Dockerfile
 create mode 100644 src/slice/__init__.py
 create mode 100644 src/slice/client/SliceClient.py
 create mode 100644 src/slice/client/__init__.py
 create mode 100755 src/slice/genproto.sh
 create mode 100644 src/slice/old_code/ConstraintsChecker.py
 create mode 100644 src/slice/old_code/SliceCheckers.py
 create mode 100644 src/slice/old_code/Tools.py
 create mode 100644 src/slice/old_code/Tools_2.py
 create mode 100644 src/slice/proto/__init__.py
 create mode 100644 src/slice/proto/context_pb2.py
 create mode 100644 src/slice/proto/kpi_sample_types_pb2.py
 create mode 100644 src/slice/proto/service_pb2.py
 create mode 100644 src/slice/proto/slice_pb2.py
 create mode 100644 src/slice/proto/slice_pb2_grpc.py
 create mode 100644 src/slice/requirements.in
 create mode 100644 src/slice/service/SliceService.py
 create mode 100644 src/slice/service/SliceServiceServicerImpl.py
 create mode 100644 src/slice/service/__init__.py
 create mode 100644 src/slice/service/__main__.py
 create mode 100644 src/slice/tests/__init__.py
 create mode 100644 src/slice/tests/test_unitary.py
 create mode 100644 src/tests/oeccpsc22/README.md
 create mode 100644 src/tests/oeccpsc22/__init__.py
 create mode 100755 src/tests/oeccpsc22/deploy_in_kubernetes.sh
 create mode 100755 src/tests/oeccpsc22/dump_logs.sh
 create mode 100644 src/tests/oeccpsc22/expose_services_teraflow_1.yaml
 create mode 100644 src/tests/oeccpsc22/expose_services_teraflow_2.yaml
 create mode 100755 src/tests/oeccpsc22/run_test_01_bootstrap.sh
 create mode 100755 src/tests/oeccpsc22/run_test_02_create_interdomain_slice.sh
 create mode 100755 src/tests/oeccpsc22/run_test_03_delete_interdomain_slice.sh
 create mode 100755 src/tests/oeccpsc22/run_test_04_cleanup.sh
 create mode 100755 src/tests/oeccpsc22/show_deploy.sh
 create mode 100644 src/tests/oeccpsc22/tests/.gitignore
 create mode 100644 src/tests/oeccpsc22/tests/Objects_Domain_1.py
 create mode 100644 src/tests/oeccpsc22/tests/Objects_Domain_2.py
 create mode 100644 src/tests/oeccpsc22/tests/Objects_Service.py
 create mode 100644 src/tests/oeccpsc22/tests/Tools.py
 create mode 100644 src/tests/oeccpsc22/tests/__init__.py
 create mode 100644 src/tests/oeccpsc22/tests/test_functional_bootstrap.py
 create mode 100644 src/tests/oeccpsc22/tests/test_functional_cleanup.py
 create mode 100644 src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py
 create mode 100644 src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index bc746a534..668b5ce62 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -1,3 +1,17 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
 # stages of the cicd pipeline
 stages:
   - dependencies
@@ -21,6 +35,8 @@ include:
   - local: '/src/opticalcentralizedattackdetector/.gitlab-ci.yml'
   - local: '/src/automation/.gitlab-ci.yml'
   - local: '/src/webui/.gitlab-ci.yml'
-  - local: '/src/l3_distributedattackdetector/.gitlab-ci.yml'
-  - local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml'
-  - local: '/src/l3_attackmitigator/.gitlab-ci.yml'
+  #- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml'
+  #- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml'
+  #- local: '/src/l3_attackmitigator/.gitlab-ci.yml'
+  #- local: '/src/slice/.gitlab-ci.yml'
+  #- local: '/src/interdomain/.gitlab-ci.yml'
diff --git a/deploy_in_kubernetes.sh b/deploy_in_kubernetes.sh
index 0da87dbe5..a1b4551dd 100755
--- a/deploy_in_kubernetes.sh
+++ b/deploy_in_kubernetes.sh
@@ -131,9 +131,12 @@ for COMPONENT in $COMPONENTS; do
     printf "\n"
 done
 
-echo "Configuring DataStores and Dashboards..."
-./configure_dashboards.sh
-printf "\n\n"
+
+if [[ "$COMPONENTS" == *"webui"* ]]; then
+    echo "Configuring WebUI DataStores and Dashboards..."
+    ./configure_dashboards.sh
+    printf "\n\n"
+fi
 
 echo "Reporting Deployment..."
 kubectl --namespace $K8S_NAMESPACE get all
diff --git a/manifests/interdomainservice.yaml b/manifests/interdomainservice.yaml
new file mode 100644
index 000000000..ca30da010
--- /dev/null
+++ b/manifests/interdomainservice.yaml
@@ -0,0 +1,64 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: interdomainservice
+spec:
+  selector:
+    matchLabels:
+      app: interdomainservice
+  template:
+    metadata:
+      labels:
+        app: interdomainservice
+    spec:
+      terminationGracePeriodSeconds: 5
+      containers:
+      - name: server
+        image: registry.gitlab.com/teraflow-h2020/controller/interdomain:latest
+        imagePullPolicy: Always
+        ports:
+        - containerPort: 10010
+        env:
+        - name: LOG_LEVEL
+          value: "DEBUG"
+        readinessProbe:
+          exec:
+            command: ["/bin/grpc_health_probe", "-addr=:10010"]
+        livenessProbe:
+          exec:
+            command: ["/bin/grpc_health_probe", "-addr=:10010"]
+        resources:
+          requests:
+            cpu: 250m
+            memory: 512Mi
+          limits:
+            cpu: 700m
+            memory: 1024Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: interdomainservice
+spec:
+  type: ClusterIP
+  selector:
+    app: interdomainservice
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 10010
+    targetPort: 10010
diff --git a/manifests/sliceservice.yaml b/manifests/sliceservice.yaml
new file mode 100644
index 000000000..eeed3776c
--- /dev/null
+++ b/manifests/sliceservice.yaml
@@ -0,0 +1,64 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+  name: sliceservice
+spec:
+  selector:
+    matchLabels:
+      app: sliceservice
+  template:
+    metadata:
+      labels:
+        app: sliceservice
+    spec:
+      terminationGracePeriodSeconds: 5
+      containers:
+      - name: server
+        image: registry.gitlab.com/teraflow-h2020/controller/slice:latest
+        imagePullPolicy: Always
+        ports:
+        - containerPort: 4040
+        env:
+        - name: LOG_LEVEL
+          value: "DEBUG"
+        readinessProbe:
+          exec:
+            command: ["/bin/grpc_health_probe", "-addr=:4040"]
+        livenessProbe:
+          exec:
+            command: ["/bin/grpc_health_probe", "-addr=:4040"]
+        resources:
+          requests:
+            cpu: 250m
+            memory: 512Mi
+          limits:
+            cpu: 700m
+            memory: 1024Mi
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: sliceservice
+spec:
+  type: ClusterIP
+  selector:
+    app: sliceservice
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 4040
+    targetPort: 4040
diff --git a/manifests/webuiservice.yaml b/manifests/webuiservice.yaml
index be7ad73d7..8c7c3773c 100644
--- a/manifests/webuiservice.yaml
+++ b/manifests/webuiservice.yaml
@@ -71,14 +71,14 @@ spec:
             path: /robots.txt
             port: 3000
             scheme: HTTP
-          initialDelaySeconds: 5
-          periodSeconds: 5
+          initialDelaySeconds: 10
+          periodSeconds: 30
           successThreshold: 1
           timeoutSeconds: 2
         livenessProbe:
           failureThreshold: 3
-          initialDelaySeconds: 5
-          periodSeconds: 5
+          initialDelaySeconds: 30
+          periodSeconds: 10
           successThreshold: 1
           tcpSocket:
             port: 3000
diff --git a/oeccpsc22 b/oeccpsc22
new file mode 120000
index 000000000..4f55befad
--- /dev/null
+++ b/oeccpsc22
@@ -0,0 +1 @@
+src/tests/oeccpsc22/
\ No newline at end of file
diff --git a/proto/context.proto b/proto/context.proto
index 057f44c9b..bc0bfa0c6 100644
--- a/proto/context.proto
+++ b/proto/context.proto
@@ -53,6 +53,13 @@ service ContextService {
   rpc RemoveService      (ServiceId   ) returns (       Empty           ) {}
   rpc GetServiceEvents   (Empty       ) returns (stream ServiceEvent    ) {}
 
+  rpc ListSliceIds       (ContextId   ) returns (       SliceIdList     ) {}
+  rpc ListSlices         (ContextId   ) returns (       SliceList       ) {}
+  rpc GetSlice           (SliceId     ) returns (       Slice           ) {}
+  rpc SetSlice           (Slice       ) returns (       SliceId         ) {}
+  rpc RemoveSlice        (SliceId     ) returns (       Empty           ) {}
+  rpc GetSliceEvents     (Empty       ) returns (stream SliceEvent      ) {}
+
   rpc ListConnectionIds  (ServiceId   ) returns (       ConnectionIdList) {}
   rpc ListConnections    (ServiceId   ) returns (       ConnectionList  ) {}
   rpc GetConnection      (ConnectionId) returns (       Connection      ) {}
@@ -253,6 +260,45 @@ message ServiceEvent {
   ServiceId service_id = 2;
 }
 
+// ----- Slice ---------------------------------------------------------------------------------------------------------
+message SliceId {
+  ContextId context_id = 1;
+  Uuid slice_uuid = 2;
+}
+
+message Slice {
+  SliceId slice_id = 1;
+  repeated EndPointId slice_endpoint_ids = 2;
+  repeated Constraint slice_constraints = 3;
+  repeated ServiceId slice_service_ids = 4;
+  repeated SliceId slice_subslice_ids = 5;
+  SliceStatus slice_status = 6;
+}
+
+enum SliceStatusEnum {
+  SLICESTATUS_UNDEFINED = 0;
+  SLICESTATUS_PLANNED   = 1;
+  SLICESTATUS_INIT      = 2;
+  SLICESTATUS_ACTIVE    = 3;
+  SLICESTATUS_DEINIT    = 4;
+}
+
+message SliceStatus {
+  SliceStatusEnum slice_status = 1;
+}
+
+message SliceIdList {
+  repeated SliceId slice_ids = 1;
+}
+
+message SliceList {
+  repeated Slice slices = 1;
+}
+
+message SliceEvent {
+  Event event = 1;
+  SliceId slice_id = 2;
+}
 
 // ----- Connection ----------------------------------------------------------------------------------------------------
 message ConnectionId {
diff --git a/proto/interdomain.proto b/proto/interdomain.proto
index 7088586e2..735d4c1cd 100644
--- a/proto/interdomain.proto
+++ b/proto/interdomain.proto
@@ -12,23 +12,15 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//Example of topology
 syntax = "proto3";
 package interdomain;
 
 import "context.proto";
-import "slice.proto";
 
 service InterdomainService {
-  rpc Authenticate (context.TeraFlowController) returns (context.AuthenticationResult) {}
-  rpc LookUpSlice(slice.TransportSlice) returns (slice.SliceId) {} //Slice component or from interdomain component
-  rpc OrderSliceFromCatalog(slice.TransportSlice) returns (slice.SliceStatus) {}
-  rpc CreateSliceAndAddToCatalog(slice.TransportSlice) returns (slice.SliceStatus) {}
+  rpc Authenticate              (context.TeraFlowController) returns (context.AuthenticationResult) {}
+  rpc RequestSlice              (context.Slice             ) returns (context.SliceId             ) {}
+  rpc LookUpSlice               (context.Slice             ) returns (context.SliceId             ) {}
+  rpc OrderSliceFromCatalog     (context.Slice             ) returns (context.Slice               ) {}
+  rpc CreateSliceAndAddToCatalog(context.Slice             ) returns (context.Slice               ) {}
 }
-
-
-
-
-
-
-
diff --git a/proto/slice.proto b/proto/slice.proto
index 73e945a40..9c518c9da 100644
--- a/proto/slice.proto
+++ b/proto/slice.proto
@@ -12,43 +12,13 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//Example of topology
 syntax = "proto3";
 package slice;
 
 import "context.proto";
 
 service SliceService {
-  rpc CreateUpdateSlice (TransportSlice) returns (SliceStatus) {}
-  rpc DeleteSlice (TransportSlice) returns (context.Empty) {}
-}
-
-message SliceEndpoint {
-  context.EndPoint port_id = 1;
-}
-
-message TransportSlice {
-  SliceId slice_id = 1;
-  repeated slice.SliceEndpoint endpoints = 2;
-  repeated context.Constraint constraints = 3;
-  repeated context.ServiceId services = 4;
-  repeated SliceId subSlicesId = 5;
-  SliceStatus status = 6;
-}
-
-message SliceId {
-  context.ContextId contextId = 1;
-  context.Uuid slice_id = 2;
-}
-
-message SliceStatus {
-  slice.SliceId slice_id = 1;
-  SliceStatusEnum status = 2;
-}
-
-enum SliceStatusEnum {
-  PLANNED = 0;
-  INIT = 1;
-  ACTIVE = 2;
-  DEINIT = 3;
+  rpc CreateSlice(context.Slice  ) returns (context.SliceId) {}
+  rpc UpdateSlice(context.Slice  ) returns (context.SliceId) {}
+  rpc DeleteSlice(context.SliceId) returns (context.Empty  ) {}
 }
diff --git a/report_coverage_slice.sh b/report_coverage_slice.sh
new file mode 100755
index 000000000..f783ec069
--- /dev/null
+++ b/report_coverage_slice.sh
@@ -0,0 +1,3 @@
+#!/bin/bash
+
+./report_coverage_all.sh | grep --color -E -i "^slice/.*$|$"
diff --git a/scripts/run_tests_locally-slice.sh b/scripts/run_tests_locally-slice.sh
new file mode 100755
index 000000000..adad39b5b
--- /dev/null
+++ b/scripts/run_tests_locally-slice.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=service.log -o log_file_level=DEBUG
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    slice/tests/test_unitary.py
diff --git a/scripts/run_tests_locally.sh b/scripts/run_tests_locally.sh
index 1655d875e..633510a54 100755
--- a/scripts/run_tests_locally.sh
+++ b/scripts/run_tests_locally.sh
@@ -94,3 +94,6 @@ coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
 
 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
     monitoring/tests/test_unitary.py
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    slice/tests/test_unitary.py
diff --git a/src/common/database/api/context/slice/SliceStatus.py b/src/common/database/api/context/slice/SliceStatus.py
new file mode 100644
index 000000000..d97b39449
--- /dev/null
+++ b/src/common/database/api/context/slice/SliceStatus.py
@@ -0,0 +1,31 @@
+from enum import Enum
+
+class SliceStatus(Enum):
+    PLANNED = 0
+    INIT    = 1
+    ACTIVE  = 2
+    DEINIT  = 3
+
+ANY_TO_ENUM = {
+    0: SliceStatus.PLANNED,
+    1: SliceStatus.INIT,
+    2: SliceStatus.ACTIVE,
+    3: SliceStatus.DEINIT,
+
+    '0': SliceStatus.PLANNED,
+    '1': SliceStatus.INIT,
+    '2': SliceStatus.ACTIVE,
+    '3': SliceStatus.DEINIT,
+
+    'planned': SliceStatus.PLANNED,
+    'init': SliceStatus.INIT,
+    'active': SliceStatus.ACTIVE,
+    'deinit': SliceStatus.DEINIT,
+}
+
+def slicestatus_enum_values():
+    return {m.value for m in SliceStatus.__members__.values()}
+
+def to_slicestatus_enum(int_or_str):
+    if isinstance(int_or_str, str): int_or_str = int_or_str.lower()
+    return ANY_TO_ENUM.get(int_or_str)
diff --git a/src/common/database/api/context/slice/__init__.py b/src/common/database/api/context/slice/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/common/logger.py b/src/common/logger.py
index a0e9997cd..c90e0bcf3 100644
--- a/src/common/logger.py
+++ b/src/common/logger.py
@@ -1,6 +1,6 @@
 #!/usr/bin/python
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
diff --git a/src/common/rpc_method_wrapper/Decorator.py b/src/common/rpc_method_wrapper/Decorator.py
index 212481b73..31dc4b82b 100644
--- a/src/common/rpc_method_wrapper/Decorator.py
+++ b/src/common/rpc_method_wrapper/Decorator.py
@@ -17,6 +17,7 @@ from enum import Enum
 from typing import Dict, List
 from prometheus_client import Counter, Histogram
 from prometheus_client.metrics import MetricWrapperBase
+from common.tools.grpc.Tools import grpc_message_to_json_string
 from .ServiceExceptions import ServiceException
 
 class RequestConditionEnum(Enum):
@@ -62,9 +63,9 @@ def safe_and_metered_rpc_method(metrics : Dict[str, MetricWrapperBase], logger :
         def inner_wrapper(self, request, grpc_context : grpc.ServicerContext):
             COUNTER_STARTED.inc()
             try:
-                logger.debug('{:s} request: {:s}'.format(function_name, str(request)))
+                logger.debug('{:s} request: {:s}'.format(function_name, grpc_message_to_json_string(request)))
                 reply = func(self, request, grpc_context)
-                logger.debug('{:s} reply: {:s}'.format(function_name, str(reply)))
+                logger.debug('{:s} reply: {:s}'.format(function_name, grpc_message_to_json_string(reply)))
                 COUNTER_COMPLETED.inc()
                 return reply
             except ServiceException as e:   # pragma: no cover (ServiceException not thrown)
diff --git a/src/common/tests/MockServicerImpl_Slice.py b/src/common/tests/MockServicerImpl_Slice.py
new file mode 100644
index 000000000..5fd349ee1
--- /dev/null
+++ b/src/common/tests/MockServicerImpl_Slice.py
@@ -0,0 +1,45 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from common.Settings import get_setting
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from slice.proto.context_pb2 import Empty, Slice, SliceId, SliceStatusEnum
+from slice.proto.slice_pb2_grpc import SliceServiceServicer
+
+LOGGER = logging.getLogger(__name__)
+
+class MockServicerImpl_Slice(SliceServiceServicer):
+    def __init__(self):
+        LOGGER.info('[__init__] Creating Servicer...')
+        self.context_client = ContextClient(
+            get_setting('CONTEXTSERVICE_SERVICE_HOST'),
+            get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC'))
+        LOGGER.info('[__init__] Servicer Created')
+
+    def CreateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
+        LOGGER.info('[CreateSlice] request={:s}'.format(grpc_message_to_json_string(request)))
+        return self.context_client.SetSlice(request)
+
+    def UpdateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
+        LOGGER.info('[UpdateSlice] request={:s}'.format(grpc_message_to_json_string(request)))
+        slice_ = Slice()
+        slice_.CopyFrom(request)
+        slice_.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_ACTIVE # pylint: disable=no-member
+        return self.context_client.SetSlice(slice_)
+
+    def DeleteSlice(self, request : SliceId, context : grpc.ServicerContext) -> Empty:
+        LOGGER.info('[DeleteSlice] request={:s}'.format(grpc_message_to_json_string(request)))
+        return self.context_client.RemoveSlice(request)
diff --git a/src/common/tools/client/RetryDecorator.py b/src/common/tools/client/RetryDecorator.py
index d7bcdb42d..9a1c0d69f 100644
--- a/src/common/tools/client/RetryDecorator.py
+++ b/src/common/tools/client/RetryDecorator.py
@@ -57,7 +57,7 @@ def delay_linear(initial=0, increment=0, maximum=None):
 
 def delay_exponential(initial=1, increment=1, maximum=None):
     def compute(num_try):
-        delay = initial * pow((num_try - 1), increment)
+        delay = initial * pow(increment, (num_try - 1))
         if maximum is not None: delay = max(delay, maximum)
         return delay
     return compute
diff --git a/src/common/tools/grpc/Tools.py b/src/common/tools/grpc/Tools.py
index 7c6a74348..f0c72a36f 100644
--- a/src/common/tools/grpc/Tools.py
+++ b/src/common/tools/grpc/Tools.py
@@ -16,8 +16,9 @@ import json
 from google.protobuf.json_format import MessageToDict
 
 def grpc_message_to_json(
-    message, including_default_value_fields=True, preserving_proto_field_name=True, use_integers_for_enums=False):
-
+        message, including_default_value_fields=True, preserving_proto_field_name=True, use_integers_for_enums=False
+    ):
+    if not hasattr(message, 'DESCRIPTOR'): return json.dumps(str(message), sort_keys=True) # not a gRPC message
     return MessageToDict(
         message, including_default_value_fields=including_default_value_fields,
         preserving_proto_field_name=preserving_proto_field_name, use_integers_for_enums=use_integers_for_enums)
diff --git a/src/compute/Dockerfile b/src/compute/Dockerfile
index 6d3cafda9..bb10332d1 100644
--- a/src/compute/Dockerfile
+++ b/src/compute/Dockerfile
@@ -46,6 +46,7 @@ COPY common/. common
 COPY compute/. compute
 COPY context/. context
 COPY service/. service
+COPY slice/. slice
 
 # Start compute service
 ENTRYPOINT ["python", "-m", "compute.service"]
diff --git a/src/compute/genproto.sh b/src/compute/genproto.sh
index c991aaf01..0c0245c3e 100755
--- a/src/compute/genproto.sh
+++ b/src/compute/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,14 +14,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto service.proto
diff --git a/src/compute/proto/context_pb2.py b/src/compute/proto/context_pb2.py
index 68602b16f..50d501d3a 100644
--- a/src/compute/proto/context_pb2.py
+++ b/src/compute/proto/context_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xad\x10\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
   ,
   dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
 
@@ -55,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3703,
-  serialized_end=3809,
+  serialized_start=4310,
+  serialized_end=4416,
 )
 _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
 
@@ -101,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3812,
-  serialized_end=4009,
+  serialized_start=4419,
+  serialized_end=4616,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
 
@@ -132,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4012,
-  serialized_end=4155,
+  serialized_start=4619,
+  serialized_end=4762,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
 
@@ -168,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4158,
-  serialized_end=4287,
+  serialized_start=4765,
+  serialized_end=4894,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
 
@@ -204,12 +204,53 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4290,
-  serialized_end=4426,
+  serialized_start=4897,
+  serialized_end=5033,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
 
 ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
 _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   name='ConfigActionEnum',
   full_name='context.ConfigActionEnum',
@@ -235,8 +276,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4428,
-  serialized_end=4521,
+  serialized_start=5177,
+  serialized_end=5270,
 )
 _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
 
@@ -262,6 +303,11 @@ SERVICESTATUS_UNDEFINED = 0
 SERVICESTATUS_PLANNED = 1
 SERVICESTATUS_ACTIVE = 2
 SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
 CONFIGACTION_UNDEFINED = 0
 CONFIGACTION_SET = 1
 CONFIGACTION_DELETE = 2
@@ -1421,6 +1467,247 @@ _SERVICEEVENT = _descriptor.Descriptor(
 )
 
 
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
 _CONNECTIONID = _descriptor.Descriptor(
   name='ConnectionId',
   full_name='context.ConnectionId',
@@ -1448,8 +1735,8 @@ _CONNECTIONID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2604,
-  serialized_end=2658,
+  serialized_start=3211,
+  serialized_end=3265,
 )
 
 
@@ -1501,8 +1788,8 @@ _CONNECTION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2661,
-  serialized_end=2857,
+  serialized_start=3268,
+  serialized_end=3464,
 )
 
 
@@ -1533,8 +1820,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2859,
-  serialized_end=2924,
+  serialized_start=3466,
+  serialized_end=3531,
 )
 
 
@@ -1565,8 +1852,8 @@ _CONNECTIONLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2926,
-  serialized_end=2984,
+  serialized_start=3533,
+  serialized_end=3591,
 )
 
 
@@ -1604,8 +1891,8 @@ _CONNECTIONEVENT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2986,
-  serialized_end=3080,
+  serialized_start=3593,
+  serialized_end=3687,
 )
 
 
@@ -1650,8 +1937,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3083,
-  serialized_end=3213,
+  serialized_start=3690,
+  serialized_end=3820,
 )
 
 
@@ -1696,8 +1983,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3216,
-  serialized_end=3350,
+  serialized_start=3823,
+  serialized_end=3957,
 )
 
 
@@ -1742,8 +2029,8 @@ _CONFIGRULE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3352,
-  serialized_end=3453,
+  serialized_start=3959,
+  serialized_end=4060,
 )
 
 
@@ -1781,8 +2068,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3455,
-  serialized_end=3518,
+  serialized_start=4062,
+  serialized_end=4125,
 )
 
 
@@ -1827,8 +2114,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3520,
-  serialized_end=3614,
+  serialized_start=4127,
+  serialized_end=4221,
 )
 
 
@@ -1866,8 +2153,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3616,
-  serialized_end=3701,
+  serialized_start=4223,
+  serialized_end=4308,
 )
 
 _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
@@ -1921,6 +2208,19 @@ _SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
 _SERVICELIST.fields_by_name['services'].message_type = _SERVICE
 _SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
 _SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
 _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
 _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
 _CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
@@ -1969,6 +2269,12 @@ DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
 DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
 DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
 DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
 DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
 DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
 DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
@@ -1985,6 +2291,7 @@ DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
 DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
 DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
 DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
 DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -2205,6 +2512,48 @@ ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_messag
   })
 _sym_db.RegisterMessage(ServiceEvent)
 
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
 ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
   'DESCRIPTOR' : _CONNECTIONID,
   '__module__' : 'context_pb2'
@@ -2291,8 +2640,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=4524,
-  serialized_end=6617,
+  serialized_start=5273,
+  serialized_end=7688,
   methods=[
   _descriptor.MethodDescriptor(
     name='ListContextIds',
@@ -2594,10 +2943,70 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='ListConnectionIds',
     full_name='context.ContextService.ListConnectionIds',
-    index=30,
+    index=36,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONIDLIST,
@@ -2607,7 +3016,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='ListConnections',
     full_name='context.ContextService.ListConnections',
-    index=31,
+    index=37,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONLIST,
@@ -2617,7 +3026,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnection',
     full_name='context.ContextService.GetConnection',
-    index=32,
+    index=38,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_CONNECTION,
@@ -2627,7 +3036,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetConnection',
     full_name='context.ContextService.SetConnection',
-    index=33,
+    index=39,
     containing_service=None,
     input_type=_CONNECTION,
     output_type=_CONNECTIONID,
@@ -2637,7 +3046,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='RemoveConnection',
     full_name='context.ContextService.RemoveConnection',
-    index=34,
+    index=40,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_EMPTY,
@@ -2647,7 +3056,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnectionEvents',
     full_name='context.ContextService.GetConnectionEvents',
-    index=35,
+    index=41,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_CONNECTIONEVENT,
diff --git a/src/compute/proto/service_pb2.py b/src/compute/proto/service_pb2.py
index 7a006915b..8e2806c76 100644
--- a/src/compute/proto/service_pb2.py
+++ b/src/compute/proto/service_pb2.py
@@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xfd\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12\x42\n\x11GetConnectionList\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x62\x06proto3'
+  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xb9\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
   ,
   dependencies=[context__pb2.DESCRIPTOR,])
 
@@ -38,7 +38,7 @@ _SERVICESERVICE = _descriptor.ServiceDescriptor(
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
   serialized_start=42,
-  serialized_end=295,
+  serialized_end=227,
   methods=[
   _descriptor.MethodDescriptor(
     name='CreateService',
@@ -70,16 +70,6 @@ _SERVICESERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
-  _descriptor.MethodDescriptor(
-    name='GetConnectionList',
-    full_name='service.ServiceService.GetConnectionList',
-    index=3,
-    containing_service=None,
-    input_type=context__pb2._SERVICEID,
-    output_type=context__pb2._CONNECTIONLIST,
-    serialized_options=None,
-    create_key=_descriptor._internal_create_key,
-  ),
 ])
 _sym_db.RegisterServiceDescriptor(_SERVICESERVICE)
 
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py
index 9420517e1..b7f377254 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/Constants.py
@@ -25,4 +25,30 @@ BEARER_MAPPINGS = {
     'R2-EMU:13/2/1': ('R2-EMU', '13/2/1', '12.12.12.1', '65000:120', 450, '3.4.2.1', 24),
     'R3-INF:13/2/1': ('R3-INF', '13/2/1', '20.20.20.1', '65000:200', 500, '3.3.1.1', 24),
     'R4-EMU:13/2/1': ('R4-EMU', '13/2/1', '22.22.22.1', '65000:220', 550, '3.4.1.1', 24),
+
+    'R1@D1:3/1': ('R1@D1', '3/1', '10.0.1.1', '65001:101', 100, '1.1.3.1', 24),
+    'R1@D1:3/2': ('R1@D1', '3/2', '10.0.1.1', '65001:101', 100, '1.1.3.2', 24),
+    'R1@D1:3/3': ('R1@D1', '3/3', '10.0.1.1', '65001:101', 100, '1.1.3.3', 24),
+    'R2@D1:3/1': ('R2@D1', '3/1', '10.0.1.2', '65001:102', 100, '1.2.3.1', 24),
+    'R2@D1:3/2': ('R2@D1', '3/2', '10.0.1.2', '65001:102', 100, '1.2.3.2', 24),
+    'R2@D1:3/3': ('R2@D1', '3/3', '10.0.1.2', '65001:102', 100, '1.2.3.3', 24),
+    'R3@D1:3/1': ('R3@D1', '3/1', '10.0.1.3', '65001:103', 100, '1.3.3.1', 24),
+    'R3@D1:3/2': ('R3@D1', '3/2', '10.0.1.3', '65001:103', 100, '1.3.3.2', 24),
+    'R3@D1:3/3': ('R3@D1', '3/3', '10.0.1.3', '65001:103', 100, '1.3.3.3', 24),
+    'R4@D1:3/1': ('R4@D1', '3/1', '10.0.1.4', '65001:104', 100, '1.4.3.1', 24),
+    'R4@D1:3/2': ('R4@D1', '3/2', '10.0.1.4', '65001:104', 100, '1.4.3.2', 24),
+    'R4@D1:3/3': ('R4@D1', '3/3', '10.0.1.4', '65001:104', 100, '1.4.3.3', 24),
+
+    'R1@D2:3/1': ('R1@D2', '3/1', '10.0.2.1', '65002:101', 100, '2.1.3.1', 24),
+    'R1@D2:3/2': ('R1@D2', '3/2', '10.0.2.1', '65002:101', 100, '2.1.3.2', 24),
+    'R1@D2:3/3': ('R1@D2', '3/3', '10.0.2.1', '65002:101', 100, '2.1.3.3', 24),
+    'R2@D2:3/1': ('R2@D2', '3/1', '10.0.2.2', '65002:102', 100, '2.2.3.1', 24),
+    'R2@D2:3/2': ('R2@D2', '3/2', '10.0.2.2', '65002:102', 100, '2.2.3.2', 24),
+    'R2@D2:3/3': ('R2@D2', '3/3', '10.0.2.2', '65002:102', 100, '2.2.3.3', 24),
+    'R3@D2:3/1': ('R3@D2', '3/1', '10.0.2.3', '65002:103', 100, '2.3.3.1', 24),
+    'R3@D2:3/2': ('R3@D2', '3/2', '10.0.2.3', '65002:103', 100, '2.3.3.2', 24),
+    'R3@D2:3/3': ('R3@D2', '3/3', '10.0.2.3', '65002:103', 100, '2.3.3.3', 24),
+    'R4@D2:3/1': ('R4@D2', '3/1', '10.0.2.4', '65002:104', 100, '2.4.3.1', 24),
+    'R4@D2:3/2': ('R4@D2', '3/2', '10.0.2.4', '65002:104', 100, '2.4.3.2', 24),
+    'R4@D2:3/3': ('R4@D2', '3/3', '10.0.2.4', '65002:104', 100, '2.4.3.3', 24),
 }
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py
index 6a91e6ae1..27489410f 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py
@@ -19,10 +19,11 @@ from flask_restful import Resource
 from common.Constants import DEFAULT_CONTEXT_UUID
 from common.Settings import get_setting
 from context.client.ContextClient import ContextClient
-from context.proto.context_pb2 import ServiceId
+from context.proto.context_pb2 import ServiceId, SliceStatusEnum
 from service.client.ServiceClient import ServiceClient
 from service.proto.context_pb2 import ServiceStatusEnum
 from .tools.Authentication import HTTP_AUTH
+from .tools.ContextMethods import get_service, get_slice
 from .tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK, HTTP_SERVERERROR
 
 LOGGER = logging.getLogger(__name__)
@@ -40,21 +41,30 @@ class L2VPN_Service(Resource):
         LOGGER.debug('VPN_Id: {:s}'.format(str(vpn_id)))
         LOGGER.debug('Request: {:s}'.format(str(request)))
 
-        # pylint: disable=no-member
-        service_id_request = ServiceId()
-        service_id_request.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID
-        service_id_request.service_uuid.uuid = vpn_id
+        response = jsonify({})
 
         try:
-            service_reply = self.context_client.GetService(service_id_request)
-            if service_reply.service_id != service_id_request: # pylint: disable=no-member
-                raise Exception('Service retrieval failed. Wrong Service Id was returned')
-            service_ready_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE
-            service_status = service_reply.service_status.service_status
-            response = jsonify({})
-            response.status_code = HTTP_OK if service_status == service_ready_status else HTTP_GATEWAYTIMEOUT
+            target = get_service(self.context_client, vpn_id)
+            if target is not None:
+                if target.service_id.service_uuid.uuid != vpn_id: # pylint: disable=no-member
+                    raise Exception('Service retrieval failed. Wrong Service Id was returned')
+                service_ready_status = ServiceStatusEnum.SERVICESTATUS_ACTIVE
+                service_status = target.service_status.service_status # pylint: disable=no-member
+                response.status_code = HTTP_OK if service_status == service_ready_status else HTTP_GATEWAYTIMEOUT
+                return response
+
+            target = get_slice(self.context_client, vpn_id)
+            if target is not None:
+                if target.slice_id.slice_uuid.uuid != vpn_id: # pylint: disable=no-member
+                    raise Exception('Slice retrieval failed. Wrong Slice Id was returned')
+                slice_ready_status = SliceStatusEnum.SLICESTATUS_ACTIVE
+                slice_status = target.slice_status.slice_status # pylint: disable=no-member
+                response.status_code = HTTP_OK if slice_status == slice_ready_status else HTTP_GATEWAYTIMEOUT
+                return response
+
+            raise Exception('VPN({:s}) not found in database'.format(str(vpn_id)))
         except Exception as e: # pylint: disable=broad-except
-            LOGGER.exception('Something went wrong Retrieving Service {:s}'.format(str(request)))
+            LOGGER.exception('Something went wrong Retrieving VPN({:s})'.format(str(request)))
             response = jsonify({'error': str(e)})
             response.status_code = HTTP_SERVERERROR
         return response
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py
index 191166a74..6d39cfe2d 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py
@@ -22,6 +22,8 @@ from common.Constants import DEFAULT_CONTEXT_UUID
 from common.Settings import get_setting
 from service.client.ServiceClient import ServiceClient
 from service.proto.context_pb2 import Service, ServiceStatusEnum, ServiceTypeEnum
+from slice.client.SliceClient import SliceClient
+from slice.proto.context_pb2 import SliceStatusEnum, Slice
 from .schemas.vpn_service import SCHEMA_VPN_SERVICE
 from .tools.Authentication import HTTP_AUTH
 from .tools.HttpStatusCodes import HTTP_CREATED, HTTP_SERVERERROR
@@ -34,6 +36,8 @@ class L2VPN_Services(Resource):
         super().__init__()
         self.service_client = ServiceClient(
             get_setting('SERVICESERVICE_SERVICE_HOST'), get_setting('SERVICESERVICE_SERVICE_PORT_GRPC'))
+        self.slice_client = SliceClient(
+            get_setting('SLICESERVICE_SERVICE_HOST'), get_setting('SLICESERVICE_SERVICE_PORT_GRPC'))
 
     @HTTP_AUTH.login_required
     def get(self):
@@ -48,17 +52,29 @@ class L2VPN_Services(Resource):
 
         vpn_services : List[Dict] = request_data['ietf-l2vpn-svc:vpn-service']
         for vpn_service in vpn_services:
-            # pylint: disable=no-member
-            service_request = Service()
-            service_request.service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID
-            service_request.service_id.service_uuid.uuid = vpn_service['vpn-id']
-            service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
-            service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
-
             try:
-                service_reply = self.service_client.CreateService(service_request)
-                if service_reply != service_request.service_id: # pylint: disable=no-member
-                    raise Exception('Service creation failed. Wrong Service Id was returned')
+                vpn_service_type = vpn_service['vpn-svc-type']
+                if vpn_service_type == 'vpws':
+                    # pylint: disable=no-member
+                    service_request = Service()
+                    service_request.service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID
+                    service_request.service_id.service_uuid.uuid = vpn_service['vpn-id']
+                    service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
+                    service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
+
+                    service_reply = self.service_client.CreateService(service_request)
+                    if service_reply != service_request.service_id: # pylint: disable=no-member
+                        raise Exception('Service creation failed. Wrong Service Id was returned')
+                elif vpn_service_type == 'vpls':
+                    # pylint: disable=no-member
+                    slice_request = Slice()
+                    slice_request.slice_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID
+                    slice_request.slice_id.slice_uuid.uuid = vpn_service['vpn-id']
+                    slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
+
+                    slice_reply = self.slice_client.CreateSlice(slice_request)
+                    if slice_reply != slice_request.slice_id: # pylint: disable=no-member
+                        raise Exception('Slice creation failed. Wrong Slice Id was returned')
 
                 response = jsonify({})
                 response.status_code = HTTP_CREATED
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py
index 6811dadac..2c0245b9a 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py
@@ -12,6 +12,7 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+from ctypes import Union
 import json, logging
 from typing import Dict
 from flask import request
@@ -19,14 +20,15 @@ from flask.json import jsonify
 from flask.wrappers import Response
 from flask_restful import Resource
 from werkzeug.exceptions import UnsupportedMediaType
-from common.Constants import DEFAULT_CONTEXT_UUID
 from common.Settings import get_setting
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
-from context.proto.context_pb2 import ConfigActionEnum, Service, ServiceId
+from context.proto.context_pb2 import ConfigActionEnum, Service, Slice
 from service.client.ServiceClient import ServiceClient
+from slice.client.SliceClient import SliceClient
 from .schemas.site_network_access import SCHEMA_SITE_NETWORK_ACCESS
 from .tools.Authentication import HTTP_AUTH
+from .tools.ContextMethods import get_service, get_slice
 from .tools.HttpStatusCodes import HTTP_NOCONTENT, HTTP_SERVERERROR
 from .tools.Validator import validate_message
 from .Constants import BEARER_MAPPINGS, DEFAULT_ADDRESS_FAMILIES, DEFAULT_BGP_AS, DEFAULT_BGP_ROUTE_TARGET, DEFAULT_MTU
@@ -44,26 +46,27 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
         raise Exception(msg.format(str(bearer_reference)))
     device_uuid,endpoint_uuid,router_id,route_distinguisher,sub_if_index,address_ip,address_prefix = mapping
 
-    # pylint: disable=no-member
-    service_id = ServiceId()
-    service_id.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID
-    service_id.service_uuid.uuid = vpn_id
+    target : Union[Service, Slice, None] = None
+    if target is None: target = get_service(context_client, vpn_id)
+    if target is None: target = get_slice  (context_client, vpn_id)
+    if target is None: raise Exception('VPN({:s}) not found in database'.format(str(vpn_id)))
 
-    service_readonly = context_client.GetService(service_id)
-    service = Service()
-    service.CopyFrom(service_readonly)
+    # pylint: disable=no-member
+    endpoint_ids = target.service_endpoint_ids if isinstance(target, Service) else target.slice_endpoint_ids
 
-    for endpoint_id in service.service_endpoint_ids:                        # pylint: disable=no-member
+    for endpoint_id in endpoint_ids:
         if endpoint_id.device_id.device_uuid.uuid != device_uuid: continue
         if endpoint_id.endpoint_uuid.uuid != endpoint_uuid: continue
         break   # found, do nothing
     else:
         # not found, add it
-        endpoint_id = service.service_endpoint_ids.add()                    # pylint: disable=no-member
+        endpoint_id = endpoint_ids.add()
         endpoint_id.device_id.device_uuid.uuid = device_uuid
         endpoint_id.endpoint_uuid.uuid = endpoint_uuid
 
-    for config_rule in service.service_config.config_rules:                 # pylint: disable=no-member
+    if isinstance(target, Slice): return target
+
+    for config_rule in target.service_config.config_rules:                  # pylint: disable=no-member
         if config_rule.resource_key != '/settings': continue
         json_settings = json.loads(config_rule.resource_value)
 
@@ -95,7 +98,7 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
         break
     else:
         # not found, add it
-        config_rule = service.service_config.config_rules.add()             # pylint: disable=no-member
+        config_rule = target.service_config.config_rules.add()              # pylint: disable=no-member
         config_rule.action = ConfigActionEnum.CONFIGACTION_SET
         config_rule.resource_key = '/settings'
         config_rule.resource_value = json.dumps({
@@ -106,7 +109,7 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
         }, sort_keys=True)
 
     endpoint_settings_key = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
-    for config_rule in service.service_config.config_rules:                 # pylint: disable=no-member
+    for config_rule in target.service_config.config_rules:                  # pylint: disable=no-member
         if config_rule.resource_key != endpoint_settings_key: continue
         json_settings = json.loads(config_rule.resource_value)
 
@@ -154,7 +157,7 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
         break
     else:
         # not found, add it
-        config_rule = service.service_config.config_rules.add()             # pylint: disable=no-member
+        config_rule = target.service_config.config_rules.add()              # pylint: disable=no-member
         config_rule.action = ConfigActionEnum.CONFIGACTION_SET
         config_rule.resource_key = endpoint_settings_key
         config_rule.resource_value = json.dumps({
@@ -166,24 +169,34 @@ def process_site_network_access(context_client : ContextClient, site_network_acc
             'address_prefix': address_prefix,
         }, sort_keys=True)
 
-    return service
+    return target
 
 def process_list_site_network_access(
-    context_client : ContextClient, service_client : ServiceClient, request_data : Dict) -> Response:
+        context_client : ContextClient, service_client : ServiceClient, slice_client : SliceClient,
+        request_data : Dict
+    ) -> Response:
 
     LOGGER.debug('Request: {:s}'.format(str(request_data)))
     validate_message(SCHEMA_SITE_NETWORK_ACCESS, request_data)
 
     errors = []
     for site_network_access in request_data['ietf-l2vpn-svc:site-network-access']:
+        sna_request = process_site_network_access(context_client, site_network_access)
+        LOGGER.debug('sna_request = {:s}'.format(grpc_message_to_json_string(sna_request)))
         try:
-            service_request = process_site_network_access(context_client, site_network_access)
-            LOGGER.debug('service_request = {:s}'.format(grpc_message_to_json_string(service_request)))
-            service_reply = service_client.UpdateService(service_request)
-            if service_reply != service_request.service_id: # pylint: disable=no-member
-                raise Exception('Service update failed. Wrong Service Id was returned')
+            if isinstance(sna_request, Service):
+                sna_reply = service_client.UpdateService(sna_request)
+                if sna_reply != sna_request.service_id: # pylint: disable=no-member
+                    raise Exception('Service update failed. Wrong Service Id was returned')
+            elif isinstance(sna_request, Slice):
+                sna_reply = slice_client.UpdateSlice(sna_request)
+                if sna_reply != sna_request.slice_id: # pylint: disable=no-member
+                    raise Exception('Slice update failed. Wrong Slice Id was returned')
+            else:
+                raise NotImplementedError('Support for Class({:s}) not implemented'.format(str(type(sna_request))))
         except Exception as e: # pylint: disable=broad-except
-            LOGGER.exception('Something went wrong Updating Service {:s}'.format(str(request)))
+            msg = 'Something went wrong Updating Service {:s}'
+            LOGGER.exception(msg.format(grpc_message_to_json_string(sna_request)))
             errors.append({'error': str(e)})
 
     response = jsonify(errors)
@@ -197,15 +210,19 @@ class L2VPN_SiteNetworkAccesses(Resource):
             get_setting('CONTEXTSERVICE_SERVICE_HOST'), get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC'))
         self.service_client = ServiceClient(
             get_setting('SERVICESERVICE_SERVICE_HOST'), get_setting('SERVICESERVICE_SERVICE_PORT_GRPC'))
+        self.slice_client = SliceClient(
+            get_setting('SLICESERVICE_SERVICE_HOST'), get_setting('SLICESERVICE_SERVICE_PORT_GRPC'))
 
     @HTTP_AUTH.login_required
     def post(self, site_id : str):
         if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
         LOGGER.debug('Site_Id: {:s}'.format(str(site_id)))
-        return process_list_site_network_access(self.context_client, self.service_client, request.json)
+        return process_list_site_network_access(
+            self.context_client, self.service_client, self.slice_client, request.json)
 
     @HTTP_AUTH.login_required
     def put(self, site_id : str):
         if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
         LOGGER.debug('Site_Id: {:s}'.format(str(site_id)))
-        return process_list_site_network_access(self.context_client, self.service_client, request.json)
+        return process_list_site_network_access(
+            self.context_client, self.service_client, self.slice_client, request.json)
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/schemas/vpn_service.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/schemas/vpn_service.py
index b224b4073..9dd8eea3d 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/schemas/vpn_service.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/schemas/vpn_service.py
@@ -36,7 +36,7 @@ SCHEMA_VPN_SERVICE = {
                 'required': ['vpn-id', 'vpn-svc-type', 'svc-topo', 'customer-name'],
                 'properties': {
                     'vpn-id': {'type': 'string', 'pattern': REGEX_UUID},
-                    'vpn-svc-type': {'enum': ['vpws']},
+                    'vpn-svc-type': {'enum': ['vpws', 'vpls']},
                     'svc-topo': {'enum': ['any-to-any']},
                     'customer-name': {'const': 'osm'},
                 },
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/ContextMethods.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/ContextMethods.py
new file mode 100644
index 000000000..79e73a28d
--- /dev/null
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/tools/ContextMethods.py
@@ -0,0 +1,39 @@
+import grpc, logging
+from typing import Optional
+from common.Constants import DEFAULT_CONTEXT_UUID
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import Service, ServiceId, Slice, SliceId
+
+LOGGER = logging.getLogger(__name__)
+
+def get_service(
+        context_client : ContextClient, service_uuid : str, context_uuid : str = DEFAULT_CONTEXT_UUID
+    ) -> Optional[Service]:
+    try:
+        # pylint: disable=no-member
+        service_id = ServiceId()
+        service_id.context_id.context_uuid.uuid = context_uuid
+        service_id.service_uuid.uuid = service_uuid
+        service_readonly = context_client.GetService(service_id)
+        service = Service()
+        service.CopyFrom(service_readonly)
+        return service
+    except grpc.RpcError:
+        #LOGGER.exception('Unable to get service({:s} / {:s})'.format(str(context_uuid), str(service_uuid)))
+        return None
+
+def get_slice(
+        context_client : ContextClient, slice_uuid : str, context_uuid : str = DEFAULT_CONTEXT_UUID
+    ) -> Optional[Slice]:
+    try:
+        # pylint: disable=no-member
+        slice_id = SliceId()
+        slice_id.context_id.context_uuid.uuid = context_uuid
+        slice_id.slice_uuid.uuid = slice_uuid
+        slice_readonly = context_client.GetSlice(slice_id)
+        slice_ = Slice()
+        slice_.CopyFrom(slice_readonly)
+        return slice_
+    except grpc.RpcError:
+        #LOGGER.exception('Unable to get slice({:s} / {:s})'.format(str(context_uuid), str(slice_uuid)))
+        return None
diff --git a/src/compute/tests/mock_osm/WimconnectorIETFL2VPN.py b/src/compute/tests/mock_osm/WimconnectorIETFL2VPN.py
index d5ce65a1e..b9639e804 100644
--- a/src/compute/tests/mock_osm/WimconnectorIETFL2VPN.py
+++ b/src/compute/tests/mock_osm/WimconnectorIETFL2VPN.py
@@ -164,178 +164,183 @@ class WimconnectorIETFL2VPN(SdnConnectorBase):
         Raises:
             SdnConnectorException: In case of error.
         """
-        if service_type == "ELINE":
-            if len(connection_points) > 2:
-                raise SdnConnectorError(
-                    "Connections between more than 2 endpoints are not supported"
+        SETTINGS = {    # min_endpoints, max_endpoints, vpn_service_type
+            'ELINE': (2,    2, 'vpws'), # Virtual Private Wire Service
+            'ELAN' : (2, None, 'vpls'), # Virtual Private LAN  Service
+        }
+        settings = SETTINGS.get(service_type)
+        if settings is None: raise NotImplementedError('Unsupported service_type({:s})'.format(str(service_type)))
+        min_endpoints, max_endpoints, vpn_service_type = settings
+
+        if max_endpoints is not None and len(connection_points) > max_endpoints:
+            msg = "Connections between more than {:d} endpoints are not supported for service_type {:s}"
+            raise SdnConnectorError(msg.format(max_endpoints, service_type))
+
+        if min_endpoints is not None and len(connection_points) < min_endpoints:
+            msg = "Connections must be of at least {:d} endpoints for service_type {:s}"
+            raise SdnConnectorError(msg.format(min_endpoints, service_type))
+
+        """First step, create the vpn service"""
+        uuid_l2vpn = str(uuid.uuid4())
+        vpn_service = {}
+        vpn_service["vpn-id"] = uuid_l2vpn
+        vpn_service["vpn-svc-type"] = vpn_service_type
+        vpn_service["svc-topo"] = "any-to-any"
+        vpn_service["customer-name"] = "osm"
+        vpn_service_list = []
+        vpn_service_list.append(vpn_service)
+        vpn_service_l = {"ietf-l2vpn-svc:vpn-service": vpn_service_list}
+        response_service_creation = None
+        conn_info = []
+        self.logger.info("Sending vpn-service :{}".format(vpn_service_l))
+
+        try:
+            endpoint_service_creation = (
+                "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/vpn-services".format(
+                    self.wim["wim_url"]
                 )
+            )
+            response_service_creation = requests.post(
+                endpoint_service_creation,
+                headers=self.headers,
+                json=vpn_service_l,
+                auth=self.auth,
+            )
+        except requests.exceptions.ConnectionError:
+            raise SdnConnectorError(
+                "Request to create service Timeout", http_code=408
+            )
+
+        if response_service_creation.status_code == 409:
+            raise SdnConnectorError(
+                "Service already exists",
+                http_code=response_service_creation.status_code,
+            )
+        elif response_service_creation.status_code != requests.codes.created:
+            raise SdnConnectorError(
+                "Request to create service not accepted",
+                http_code=response_service_creation.status_code,
+            )
+
+        """Second step, create the connections and vpn attachments"""
+        for connection_point in connection_points:
+            connection_point_wan_info = self.search_mapp(connection_point)
+            site_network_access = {}
+            connection = {}
+
+            if connection_point["service_endpoint_encapsulation_type"] != "none":
+                if (
+                    connection_point["service_endpoint_encapsulation_type"]
+                    == "dot1q"
+                ):
+                    """The connection is a VLAN"""
+                    connection["encapsulation-type"] = "dot1q-vlan-tagged"
+                    tagged = {}
+                    tagged_interf = {}
+                    service_endpoint_encapsulation_info = connection_point[
+                        "service_endpoint_encapsulation_info"
+                    ]
+
+                    if service_endpoint_encapsulation_info["vlan"] is None:
+                        raise SdnConnectorError("VLAN must be provided")
 
-            if len(connection_points) < 2:
-                raise SdnConnectorError("Connections must be of at least 2 endpoints")
-
-            """First step, create the vpn service"""
-            uuid_l2vpn = str(uuid.uuid4())
-            vpn_service = {}
-            vpn_service["vpn-id"] = uuid_l2vpn
-            vpn_service["vpn-svc-type"] = "vpws"            # Rename "vpn-scv-type" -> "vpn-svc-type"
-            vpn_service["svc-topo"] = "any-to-any"
-            vpn_service["customer-name"] = "osm"
-            vpn_service_list = []
-            vpn_service_list.append(vpn_service)
-            vpn_service_l = {"ietf-l2vpn-svc:vpn-service": vpn_service_list}
-            response_service_creation = None
-            conn_info = []
-            self.logger.info("Sending vpn-service :{}".format(vpn_service_l))
+                    tagged_interf["cvlan-id"] = service_endpoint_encapsulation_info[
+                        "vlan"
+                    ]
+                    tagged["dot1q-vlan-tagged"] = tagged_interf
+                    connection["tagged-interface"] = tagged
+                else:
+                    raise NotImplementedError("Encapsulation type not implemented")
+
+            site_network_access["connection"] = connection
+            self.logger.info("Sending connection:{}".format(connection))
+            vpn_attach = {}
+            vpn_attach["vpn-id"] = uuid_l2vpn
+            vpn_attach["site-role"] = vpn_service["svc-topo"] + "-role"
+            site_network_access["vpn-attachment"] = vpn_attach
+            self.logger.info("Sending vpn-attachement :{}".format(vpn_attach))
+            uuid_sna = str(uuid.uuid4())
+            site_network_access["network-access-id"] = uuid_sna
+            site_network_access["bearer"] = connection_point_wan_info[
+                "service_mapping_info"
+            ]["bearer"]
+            site_network_accesses = {}
+            site_network_access_list = []
+            site_network_access_list.append(site_network_access)
+            site_network_accesses[
+                "ietf-l2vpn-svc:site-network-access"
+            ] = site_network_access_list
+            conn_info_d = {}
+            conn_info_d["site"] = connection_point_wan_info["service_mapping_info"][
+                "site-id"
+            ]
+            conn_info_d["site-network-access-id"] = site_network_access[
+                "network-access-id"
+            ]
+            conn_info_d["mapping"] = None
+            conn_info.append(conn_info_d)
 
             try:
-                endpoint_service_creation = (
-                    "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/vpn-services".format(
-                        self.wim["wim_url"]
+                endpoint_site_network_access_creation = (
+                    "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/"
+                    "sites/site={}/site-network-accesses/".format(
+                        self.wim["wim_url"],
+                        connection_point_wan_info["service_mapping_info"][
+                            "site-id"
+                        ],
                     )
                 )
-                response_service_creation = requests.post(
-                    endpoint_service_creation,
+                response_endpoint_site_network_access_creation = requests.post(
+                    endpoint_site_network_access_creation,
                     headers=self.headers,
-                    json=vpn_service_l,
+                    json=site_network_accesses,
                     auth=self.auth,
                 )
-            except requests.exceptions.ConnectionError:
-                raise SdnConnectorError(
-                    "Request to create service Timeout", http_code=408
-                )
 
-            if response_service_creation.status_code == 409:
-                raise SdnConnectorError(
-                    "Service already exists",
-                    http_code=response_service_creation.status_code,
-                )
-            elif response_service_creation.status_code != requests.codes.created:
-                raise SdnConnectorError(
-                    "Request to create service not accepted",
-                    http_code=response_service_creation.status_code,
-                )
+                if (
+                    response_endpoint_site_network_access_creation.status_code
+                    == 409
+                ):
+                    self.delete_connectivity_service(vpn_service["vpn-id"])
+
+                    raise SdnConnectorError(
+                        "Site_Network_Access with ID '{}' already exists".format(
+                            site_network_access["network-access-id"]
+                        ),
+                        http_code=response_endpoint_site_network_access_creation.status_code,
+                    )
+                elif (
+                    response_endpoint_site_network_access_creation.status_code
+                    == 400
+                ):
+                    self.delete_connectivity_service(vpn_service["vpn-id"])
 
-            """Second step, create the connections and vpn attachments"""
-            for connection_point in connection_points:
-                connection_point_wan_info = self.search_mapp(connection_point)
-                site_network_access = {}
-                connection = {}
-
-                if connection_point["service_endpoint_encapsulation_type"] != "none":
-                    if (
-                        connection_point["service_endpoint_encapsulation_type"]
-                        == "dot1q"
-                    ):
-                        """The connection is a VLAN"""
-                        connection["encapsulation-type"] = "dot1q-vlan-tagged"
-                        tagged = {}
-                        tagged_interf = {}
-                        service_endpoint_encapsulation_info = connection_point[
-                            "service_endpoint_encapsulation_info"
-                        ]
-
-                        if service_endpoint_encapsulation_info["vlan"] is None:
-                            raise SdnConnectorError("VLAN must be provided")
-
-                        tagged_interf["cvlan-id"] = service_endpoint_encapsulation_info[
-                            "vlan"
-                        ]
-                        tagged["dot1q-vlan-tagged"] = tagged_interf
-                        connection["tagged-interface"] = tagged
-                    else:
-                        raise NotImplementedError("Encapsulation type not implemented")
-
-                site_network_access["connection"] = connection
-                self.logger.info("Sending connection:{}".format(connection))
-                vpn_attach = {}
-                vpn_attach["vpn-id"] = uuid_l2vpn
-                vpn_attach["site-role"] = vpn_service["svc-topo"] + "-role"
-                site_network_access["vpn-attachment"] = vpn_attach
-                self.logger.info("Sending vpn-attachement :{}".format(vpn_attach))
-                uuid_sna = str(uuid.uuid4())
-                site_network_access["network-access-id"] = uuid_sna
-                site_network_access["bearer"] = connection_point_wan_info[
-                    "service_mapping_info"
-                ]["bearer"]
-                site_network_accesses = {}
-                site_network_access_list = []
-                site_network_access_list.append(site_network_access)
-                site_network_accesses[
-                    "ietf-l2vpn-svc:site-network-access"
-                ] = site_network_access_list
-                conn_info_d = {}
-                conn_info_d["site"] = connection_point_wan_info["service_mapping_info"][
-                    "site-id"
-                ]
-                conn_info_d["site-network-access-id"] = site_network_access[
-                    "network-access-id"
-                ]
-                conn_info_d["mapping"] = None
-                conn_info.append(conn_info_d)
-
-                try:
-                    endpoint_site_network_access_creation = (
-                        "{}/restconf/data/ietf-l2vpn-svc:l2vpn-svc/"
-                        "sites/site={}/site-network-accesses/".format(
-                            self.wim["wim_url"],
+                    raise SdnConnectorError(
+                        "Site {} does not exist".format(
                             connection_point_wan_info["service_mapping_info"][
                                 "site-id"
-                            ],
-                        )
-                    )
-                    response_endpoint_site_network_access_creation = requests.post(
-                        endpoint_site_network_access_creation,
-                        headers=self.headers,
-                        json=site_network_accesses,
-                        auth=self.auth,
+                            ]
+                        ),
+                        http_code=response_endpoint_site_network_access_creation.status_code,
                     )
-
-                    if (
-                        response_endpoint_site_network_access_creation.status_code
-                        == 409
-                    ):
-                        self.delete_connectivity_service(vpn_service["vpn-id"])
-
-                        raise SdnConnectorError(
-                            "Site_Network_Access with ID '{}' already exists".format(
-                                site_network_access["network-access-id"]
-                            ),
-                            http_code=response_endpoint_site_network_access_creation.status_code,
-                        )
-                    elif (
-                        response_endpoint_site_network_access_creation.status_code
-                        == 400
-                    ):
-                        self.delete_connectivity_service(vpn_service["vpn-id"])
-
-                        raise SdnConnectorError(
-                            "Site {} does not exist".format(
-                                connection_point_wan_info["service_mapping_info"][
-                                    "site-id"
-                                ]
-                            ),
-                            http_code=response_endpoint_site_network_access_creation.status_code,
-                        )
-                    elif (
-                        response_endpoint_site_network_access_creation.status_code
-                        != requests.codes.created
-                        and response_endpoint_site_network_access_creation.status_code
-                        != requests.codes.no_content
-                    ):
-                        self.delete_connectivity_service(vpn_service["vpn-id"])
-
-                        raise SdnConnectorError(
-                            "Request no accepted",
-                            http_code=response_endpoint_site_network_access_creation.status_code,
-                        )
-                except requests.exceptions.ConnectionError:
+                elif (
+                    response_endpoint_site_network_access_creation.status_code
+                    != requests.codes.created
+                    and response_endpoint_site_network_access_creation.status_code
+                    != requests.codes.no_content
+                ):
                     self.delete_connectivity_service(vpn_service["vpn-id"])
 
-                    raise SdnConnectorError("Request Timeout", http_code=408)
+                    raise SdnConnectorError(
+                        "Request no accepted",
+                        http_code=response_endpoint_site_network_access_creation.status_code,
+                    )
+            except requests.exceptions.ConnectionError:
+                self.delete_connectivity_service(vpn_service["vpn-id"])
+
+                raise SdnConnectorError("Request Timeout", http_code=408)
 
-            return uuid_l2vpn, conn_info
-        else:
-            raise NotImplementedError
+        return uuid_l2vpn, conn_info
 
     def delete_connectivity_service(self, service_uuid, conn_info=None):
         """Disconnect multi-site endpoints previously connected
diff --git a/src/compute/tests/test_unitary.py b/src/compute/tests/test_unitary.py
index 2fa586986..1fbc74ecc 100644
--- a/src/compute/tests/test_unitary.py
+++ b/src/compute/tests/test_unitary.py
@@ -16,10 +16,12 @@ import logging, os, pytest, time
 from common.tests.MockService import MockService
 from common.tests.MockServicerImpl_Context import MockServicerImpl_Context
 from common.tests.MockServicerImpl_Service import MockServicerImpl_Service
+from common.tests.MockServicerImpl_Slice import MockServicerImpl_Slice
 from compute.Config import RESTAPI_SERVICE_PORT, RESTAPI_BASE_URL
 from compute.service.rest_server.RestServer import RestServer
 from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server
 from service.proto.service_pb2_grpc import add_ServiceServiceServicer_to_server
+from slice.proto.slice_pb2_grpc import add_SliceServiceServicer_to_server
 from .mock_osm.MockOSM import MockOSM
 from .Constants import (
     SERVICE_CONNECTION_POINTS_1, SERVICE_CONNECTION_POINTS_2, SERVICE_TYPE, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)
@@ -43,11 +45,15 @@ class MockService_ContextService(MockService):
         add_ContextServiceServicer_to_server(self.context_servicer, self.server)
         self.service_servicer = MockServicerImpl_Service()
         add_ServiceServiceServicer_to_server(self.service_servicer, self.server)
+        self.slice_servicer = MockServicerImpl_Slice()
+        add_SliceServiceServicer_to_server(self.slice_servicer, self.server)
 
 os.environ['CONTEXTSERVICE_SERVICE_HOST'] = LOCALHOST
 os.environ['CONTEXTSERVICE_SERVICE_PORT_GRPC'] = str(MOCKSERVER_GRPC_PORT)
 os.environ['SERVICESERVICE_SERVICE_HOST'] = LOCALHOST
 os.environ['SERVICESERVICE_SERVICE_PORT_GRPC'] = str(MOCKSERVER_GRPC_PORT)
+os.environ['SLICESERVICE_SERVICE_HOST'] = LOCALHOST
+os.environ['SLICESERVICE_SERVICE_PORT_GRPC'] = str(MOCKSERVER_GRPC_PORT)
 
 # NBI Plugin IETF L2VPN requires environment variables CONTEXTSERVICE_SERVICE_HOST, CONTEXTSERVICE_SERVICE_PORT_GRPC,
 # SERVICESERVICE_SERVICE_HOST, and SERVICESERVICE_SERVICE_PORT_GRPC to work properly.
diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py
index bf58ea45d..3206e4a36 100644
--- a/src/context/client/ContextClient.py
+++ b/src/context/client/ContextClient.py
@@ -15,11 +15,12 @@
 from typing import Iterator
 import grpc, logging
 from common.tools.client.RetryDecorator import retry, delay_exponential
+from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.proto.context_pb2 import (
     Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList, Context, ContextEvent, ContextId,
     ContextIdList, ContextList, Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, Empty, Link, LinkEvent,
-    LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, Topology,
-    TopologyEvent, TopologyId, TopologyIdList, TopologyList)
+    LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent,
+    SliceId, SliceIdList, SliceList, Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList)
 from context.proto.context_pb2_grpc import ContextServiceStub
 
 LOGGER = logging.getLogger(__name__)
@@ -47,252 +48,294 @@ class ContextClient:
 
     @RETRY_DECORATOR
     def ListContextIds(self, request: Empty) -> ContextIdList:
-        LOGGER.debug('ListContextIds request: {:s}'.format(str(request)))
+        LOGGER.debug('ListContextIds request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListContextIds(request)
-        LOGGER.debug('ListContextIds result: {:s}'.format(str(response)))
+        LOGGER.debug('ListContextIds result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListContexts(self, request: Empty) -> ContextList:
-        LOGGER.debug('ListContexts request: {:s}'.format(str(request)))
+        LOGGER.debug('ListContexts request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListContexts(request)
-        LOGGER.debug('ListContexts result: {:s}'.format(str(response)))
+        LOGGER.debug('ListContexts result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetContext(self, request: ContextId) -> Context:
-        LOGGER.debug('GetContext request: {:s}'.format(str(request)))
+        LOGGER.debug('GetContext request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetContext(request)
-        LOGGER.debug('GetContext result: {:s}'.format(str(response)))
+        LOGGER.debug('GetContext result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def SetContext(self, request: Context) -> ContextId:
-        LOGGER.debug('SetContext request: {:s}'.format(str(request)))
+        LOGGER.debug('SetContext request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.SetContext(request)
-        LOGGER.debug('SetContext result: {:s}'.format(str(response)))
+        LOGGER.debug('SetContext result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def RemoveContext(self, request: ContextId) -> Empty:
-        LOGGER.debug('RemoveContext request: {:s}'.format(str(request)))
+        LOGGER.debug('RemoveContext request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.RemoveContext(request)
-        LOGGER.debug('RemoveContext result: {:s}'.format(str(response)))
+        LOGGER.debug('RemoveContext result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetContextEvents(self, request: Empty) -> Iterator[ContextEvent]:
-        LOGGER.debug('GetContextEvents request: {:s}'.format(str(request)))
+        LOGGER.debug('GetContextEvents request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetContextEvents(request)
-        LOGGER.debug('GetContextEvents result: {:s}'.format(str(response)))
+        LOGGER.debug('GetContextEvents result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListTopologyIds(self, request: ContextId) -> TopologyIdList:
-        LOGGER.debug('ListTopologyIds request: {:s}'.format(str(request)))
+        LOGGER.debug('ListTopologyIds request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListTopologyIds(request)
-        LOGGER.debug('ListTopologyIds result: {:s}'.format(str(response)))
+        LOGGER.debug('ListTopologyIds result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListTopologies(self, request: ContextId) -> TopologyList:
-        LOGGER.debug('ListTopologies request: {:s}'.format(str(request)))
+        LOGGER.debug('ListTopologies request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListTopologies(request)
-        LOGGER.debug('ListTopologies result: {:s}'.format(str(response)))
+        LOGGER.debug('ListTopologies result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetTopology(self, request: TopologyId) -> Topology:
-        LOGGER.debug('GetTopology request: {:s}'.format(str(request)))
+        LOGGER.debug('GetTopology request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetTopology(request)
-        LOGGER.debug('GetTopology result: {:s}'.format(str(response)))
+        LOGGER.debug('GetTopology result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def SetTopology(self, request: Topology) -> TopologyId:
-        LOGGER.debug('SetTopology request: {:s}'.format(str(request)))
+        LOGGER.debug('SetTopology request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.SetTopology(request)
-        LOGGER.debug('SetTopology result: {:s}'.format(str(response)))
+        LOGGER.debug('SetTopology result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def RemoveTopology(self, request: TopologyId) -> Empty:
-        LOGGER.debug('RemoveTopology request: {:s}'.format(str(request)))
+        LOGGER.debug('RemoveTopology request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.RemoveTopology(request)
-        LOGGER.debug('RemoveTopology result: {:s}'.format(str(response)))
+        LOGGER.debug('RemoveTopology result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetTopologyEvents(self, request: Empty) -> Iterator[TopologyEvent]:
-        LOGGER.debug('GetTopologyEvents request: {:s}'.format(str(request)))
+        LOGGER.debug('GetTopologyEvents request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetTopologyEvents(request)
-        LOGGER.debug('GetTopologyEvents result: {:s}'.format(str(response)))
+        LOGGER.debug('GetTopologyEvents result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListDeviceIds(self, request: Empty) -> DeviceIdList:
-        LOGGER.debug('ListDeviceIds request: {:s}'.format(str(request)))
+        LOGGER.debug('ListDeviceIds request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListDeviceIds(request)
-        LOGGER.debug('ListDeviceIds result: {:s}'.format(str(response)))
+        LOGGER.debug('ListDeviceIds result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListDevices(self, request: Empty) -> DeviceList:
-        LOGGER.debug('ListDevices request: {:s}'.format(str(request)))
+        LOGGER.debug('ListDevices request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListDevices(request)
-        LOGGER.debug('ListDevices result: {:s}'.format(str(response)))
+        LOGGER.debug('ListDevices result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetDevice(self, request: DeviceId) -> Device:
-        LOGGER.debug('GetDevice request: {:s}'.format(str(request)))
+        LOGGER.debug('GetDevice request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetDevice(request)
-        LOGGER.debug('GetDevice result: {:s}'.format(str(response)))
+        LOGGER.debug('GetDevice result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def SetDevice(self, request: Device) -> DeviceId:
-        LOGGER.debug('SetDevice request: {:s}'.format(str(request)))
+        LOGGER.debug('SetDevice request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.SetDevice(request)
-        LOGGER.debug('SetDevice result: {:s}'.format(str(response)))
+        LOGGER.debug('SetDevice result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def RemoveDevice(self, request: DeviceId) -> Empty:
-        LOGGER.debug('RemoveDevice request: {:s}'.format(str(request)))
+        LOGGER.debug('RemoveDevice request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.RemoveDevice(request)
-        LOGGER.debug('RemoveDevice result: {:s}'.format(str(response)))
+        LOGGER.debug('RemoveDevice result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetDeviceEvents(self, request: Empty) -> Iterator[DeviceEvent]:
-        LOGGER.debug('GetDeviceEvents request: {:s}'.format(str(request)))
+        LOGGER.debug('GetDeviceEvents request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetDeviceEvents(request)
-        LOGGER.debug('GetDeviceEvents result: {:s}'.format(str(response)))
+        LOGGER.debug('GetDeviceEvents result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListLinkIds(self, request: Empty) -> LinkIdList:
-        LOGGER.debug('ListLinkIds request: {:s}'.format(str(request)))
+        LOGGER.debug('ListLinkIds request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListLinkIds(request)
-        LOGGER.debug('ListLinkIds result: {:s}'.format(str(response)))
+        LOGGER.debug('ListLinkIds result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListLinks(self, request: Empty) -> LinkList:
-        LOGGER.debug('ListLinks request: {:s}'.format(str(request)))
+        LOGGER.debug('ListLinks request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListLinks(request)
-        LOGGER.debug('ListLinks result: {:s}'.format(str(response)))
+        LOGGER.debug('ListLinks result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetLink(self, request: LinkId) -> Link:
-        LOGGER.debug('GetLink request: {:s}'.format(str(request)))
+        LOGGER.debug('GetLink request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetLink(request)
-        LOGGER.debug('GetLink result: {:s}'.format(str(response)))
+        LOGGER.debug('GetLink result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def SetLink(self, request: Link) -> LinkId:
-        LOGGER.debug('SetLink request: {:s}'.format(str(request)))
+        LOGGER.debug('SetLink request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.SetLink(request)
-        LOGGER.debug('SetLink result: {:s}'.format(str(response)))
+        LOGGER.debug('SetLink result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def RemoveLink(self, request: LinkId) -> Empty:
-        LOGGER.debug('RemoveLink request: {:s}'.format(str(request)))
+        LOGGER.debug('RemoveLink request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.RemoveLink(request)
-        LOGGER.debug('RemoveLink result: {:s}'.format(str(response)))
+        LOGGER.debug('RemoveLink result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetLinkEvents(self, request: Empty) -> Iterator[LinkEvent]:
-        LOGGER.debug('GetLinkEvents request: {:s}'.format(str(request)))
+        LOGGER.debug('GetLinkEvents request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetLinkEvents(request)
-        LOGGER.debug('GetLinkEvents result: {:s}'.format(str(response)))
+        LOGGER.debug('GetLinkEvents result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListServiceIds(self, request: ContextId) -> ServiceIdList:
-        LOGGER.debug('ListServiceIds request: {:s}'.format(str(request)))
+        LOGGER.debug('ListServiceIds request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListServiceIds(request)
-        LOGGER.debug('ListServiceIds result: {:s}'.format(str(response)))
+        LOGGER.debug('ListServiceIds result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListServices(self, request: ContextId) -> ServiceList:
-        LOGGER.debug('ListServices request: {:s}'.format(str(request)))
+        LOGGER.debug('ListServices request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListServices(request)
-        LOGGER.debug('ListServices result: {:s}'.format(str(response)))
+        LOGGER.debug('ListServices result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetService(self, request: ServiceId) -> Service:
-        LOGGER.debug('GetService request: {:s}'.format(str(request)))
+        LOGGER.debug('GetService request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetService(request)
-        LOGGER.debug('GetService result: {:s}'.format(str(response)))
+        LOGGER.debug('GetService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def SetService(self, request: Service) -> ServiceId:
-        LOGGER.debug('SetService request: {:s}'.format(str(request)))
+        LOGGER.debug('SetService request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.SetService(request)
-        LOGGER.debug('SetService result: {:s}'.format(str(response)))
+        LOGGER.debug('SetService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def RemoveService(self, request: ServiceId) -> Empty:
-        LOGGER.debug('RemoveService request: {:s}'.format(str(request)))
+        LOGGER.debug('RemoveService request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.RemoveService(request)
-        LOGGER.debug('RemoveService result: {:s}'.format(str(response)))
+        LOGGER.debug('RemoveService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetServiceEvents(self, request: Empty) -> Iterator[ServiceEvent]:
-        LOGGER.debug('GetServiceEvents request: {:s}'.format(str(request)))
+        LOGGER.debug('GetServiceEvents request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetServiceEvents(request)
-        LOGGER.debug('GetServiceEvents result: {:s}'.format(str(response)))
+        LOGGER.debug('GetServiceEvents result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def ListSliceIds(self, request: ContextId) -> SliceIdList:
+        LOGGER.debug('ListSliceIds request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.ListSliceIds(request)
+        LOGGER.debug('ListSliceIds result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def ListSlices(self, request: ContextId) -> SliceList:
+        LOGGER.debug('ListSlices request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.ListSlices(request)
+        LOGGER.debug('ListSlices result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def GetSlice(self, request: SliceId) -> Slice:
+        LOGGER.debug('GetSlice request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetSlice(request)
+        LOGGER.debug('GetSlice result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def SetSlice(self, request: Slice) -> SliceId:
+        LOGGER.debug('SetSlice request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.SetSlice(request)
+        LOGGER.debug('SetSlice result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def RemoveSlice(self, request: SliceId) -> Empty:
+        LOGGER.debug('RemoveSlice request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.RemoveSlice(request)
+        LOGGER.debug('RemoveSlice result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def GetSliceEvents(self, request: Empty) -> Iterator[SliceEvent]:
+        LOGGER.debug('GetSliceEvents request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetSliceEvents(request)
+        LOGGER.debug('GetSliceEvents result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListConnectionIds(self, request: ServiceId) -> ConnectionIdList:
-        LOGGER.debug('ListConnectionIds request: {:s}'.format(str(request)))
+        LOGGER.debug('ListConnectionIds request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListConnectionIds(request)
-        LOGGER.debug('ListConnectionIds result: {:s}'.format(str(response)))
+        LOGGER.debug('ListConnectionIds result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ListConnections(self, request: ServiceId) -> ConnectionList:
-        LOGGER.debug('ListConnections request: {:s}'.format(str(request)))
+        LOGGER.debug('ListConnections request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ListConnections(request)
-        LOGGER.debug('ListConnections result: {:s}'.format(str(response)))
+        LOGGER.debug('ListConnections result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetConnection(self, request: ConnectionId) -> Connection:
-        LOGGER.debug('GetConnection request: {:s}'.format(str(request)))
+        LOGGER.debug('GetConnection request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetConnection(request)
-        LOGGER.debug('GetConnection result: {:s}'.format(str(response)))
+        LOGGER.debug('GetConnection result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def SetConnection(self, request: Connection) -> ConnectionId:
-        LOGGER.debug('SetConnection request: {:s}'.format(str(request)))
+        LOGGER.debug('SetConnection request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.SetConnection(request)
-        LOGGER.debug('SetConnection result: {:s}'.format(str(response)))
+        LOGGER.debug('SetConnection result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def RemoveConnection(self, request: ConnectionId) -> Empty:
-        LOGGER.debug('RemoveConnection request: {:s}'.format(str(request)))
+        LOGGER.debug('RemoveConnection request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.RemoveConnection(request)
-        LOGGER.debug('RemoveConnection result: {:s}'.format(str(response)))
+        LOGGER.debug('RemoveConnection result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetConnectionEvents(self, request: Empty) -> Iterator[ConnectionEvent]:
-        LOGGER.debug('GetConnectionEvents request: {:s}'.format(str(request)))
+        LOGGER.debug('GetConnectionEvents request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetConnectionEvents(request)
-        LOGGER.debug('GetConnectionEvents result: {:s}'.format(str(response)))
+        LOGGER.debug('GetConnectionEvents result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
diff --git a/src/context/client/EventsCollector.py b/src/context/client/EventsCollector.py
index 3022df0a6..f35b43eab 100644
--- a/src/context/client/EventsCollector.py
+++ b/src/context/client/EventsCollector.py
@@ -32,6 +32,7 @@ class EventsCollector:
         self._device_stream     = context_client_grpc.GetDeviceEvents(Empty())
         self._link_stream       = context_client_grpc.GetLinkEvents(Empty())
         self._service_stream    = context_client_grpc.GetServiceEvents(Empty())
+        self._slice_stream      = context_client_grpc.GetSliceEvents(Empty())
         self._connection_stream = context_client_grpc.GetConnectionEvents(Empty())
 
         self._context_thread    = threading.Thread(target=self._collect, args=(self._context_stream   ,), daemon=False)
@@ -39,6 +40,7 @@ class EventsCollector:
         self._device_thread     = threading.Thread(target=self._collect, args=(self._device_stream    ,), daemon=False)
         self._link_thread       = threading.Thread(target=self._collect, args=(self._link_stream      ,), daemon=False)
         self._service_thread    = threading.Thread(target=self._collect, args=(self._service_stream   ,), daemon=False)
+        self._slice_thread      = threading.Thread(target=self._collect, args=(self._slice_stream     ,), daemon=False)
         self._connection_thread = threading.Thread(target=self._collect, args=(self._connection_stream,), daemon=False)
 
     def _collect(self, events_stream) -> None:
@@ -57,6 +59,7 @@ class EventsCollector:
         self._device_thread.start()
         self._link_thread.start()
         self._service_thread.start()
+        self._slice_thread.start()
         self._connection_thread.start()
 
     def get_event(self, block : bool = True, timeout : float = 0.1):
@@ -85,6 +88,7 @@ class EventsCollector:
         self._device_stream.cancel()
         self._link_stream.cancel()
         self._service_stream.cancel()
+        self._slice_stream.cancel()
         self._connection_stream.cancel()
 
         self._context_thread.join()
@@ -92,4 +96,5 @@ class EventsCollector:
         self._device_thread.join()
         self._link_thread.join()
         self._service_thread.join()
+        self._slice_thread.join()
         self._connection_thread.join()
diff --git a/src/context/genproto.sh b/src/context/genproto.sh
index 8302d3550..5c54cd7a2 100755
--- a/src/context/genproto.sh
+++ b/src/context/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,14 +14,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto
diff --git a/src/context/proto/context_pb2.py b/src/context/proto/context_pb2.py
index 68602b16f..50d501d3a 100644
--- a/src/context/proto/context_pb2.py
+++ b/src/context/proto/context_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xad\x10\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
   ,
   dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
 
@@ -55,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3703,
-  serialized_end=3809,
+  serialized_start=4310,
+  serialized_end=4416,
 )
 _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
 
@@ -101,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3812,
-  serialized_end=4009,
+  serialized_start=4419,
+  serialized_end=4616,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
 
@@ -132,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4012,
-  serialized_end=4155,
+  serialized_start=4619,
+  serialized_end=4762,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
 
@@ -168,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4158,
-  serialized_end=4287,
+  serialized_start=4765,
+  serialized_end=4894,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
 
@@ -204,12 +204,53 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4290,
-  serialized_end=4426,
+  serialized_start=4897,
+  serialized_end=5033,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
 
 ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
 _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   name='ConfigActionEnum',
   full_name='context.ConfigActionEnum',
@@ -235,8 +276,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4428,
-  serialized_end=4521,
+  serialized_start=5177,
+  serialized_end=5270,
 )
 _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
 
@@ -262,6 +303,11 @@ SERVICESTATUS_UNDEFINED = 0
 SERVICESTATUS_PLANNED = 1
 SERVICESTATUS_ACTIVE = 2
 SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
 CONFIGACTION_UNDEFINED = 0
 CONFIGACTION_SET = 1
 CONFIGACTION_DELETE = 2
@@ -1421,6 +1467,247 @@ _SERVICEEVENT = _descriptor.Descriptor(
 )
 
 
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
 _CONNECTIONID = _descriptor.Descriptor(
   name='ConnectionId',
   full_name='context.ConnectionId',
@@ -1448,8 +1735,8 @@ _CONNECTIONID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2604,
-  serialized_end=2658,
+  serialized_start=3211,
+  serialized_end=3265,
 )
 
 
@@ -1501,8 +1788,8 @@ _CONNECTION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2661,
-  serialized_end=2857,
+  serialized_start=3268,
+  serialized_end=3464,
 )
 
 
@@ -1533,8 +1820,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2859,
-  serialized_end=2924,
+  serialized_start=3466,
+  serialized_end=3531,
 )
 
 
@@ -1565,8 +1852,8 @@ _CONNECTIONLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2926,
-  serialized_end=2984,
+  serialized_start=3533,
+  serialized_end=3591,
 )
 
 
@@ -1604,8 +1891,8 @@ _CONNECTIONEVENT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2986,
-  serialized_end=3080,
+  serialized_start=3593,
+  serialized_end=3687,
 )
 
 
@@ -1650,8 +1937,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3083,
-  serialized_end=3213,
+  serialized_start=3690,
+  serialized_end=3820,
 )
 
 
@@ -1696,8 +1983,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3216,
-  serialized_end=3350,
+  serialized_start=3823,
+  serialized_end=3957,
 )
 
 
@@ -1742,8 +2029,8 @@ _CONFIGRULE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3352,
-  serialized_end=3453,
+  serialized_start=3959,
+  serialized_end=4060,
 )
 
 
@@ -1781,8 +2068,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3455,
-  serialized_end=3518,
+  serialized_start=4062,
+  serialized_end=4125,
 )
 
 
@@ -1827,8 +2114,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3520,
-  serialized_end=3614,
+  serialized_start=4127,
+  serialized_end=4221,
 )
 
 
@@ -1866,8 +2153,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3616,
-  serialized_end=3701,
+  serialized_start=4223,
+  serialized_end=4308,
 )
 
 _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
@@ -1921,6 +2208,19 @@ _SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
 _SERVICELIST.fields_by_name['services'].message_type = _SERVICE
 _SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
 _SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
 _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
 _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
 _CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
@@ -1969,6 +2269,12 @@ DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
 DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
 DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
 DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
 DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
 DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
 DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
@@ -1985,6 +2291,7 @@ DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
 DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
 DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
 DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
 DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -2205,6 +2512,48 @@ ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_messag
   })
 _sym_db.RegisterMessage(ServiceEvent)
 
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
 ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
   'DESCRIPTOR' : _CONNECTIONID,
   '__module__' : 'context_pb2'
@@ -2291,8 +2640,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=4524,
-  serialized_end=6617,
+  serialized_start=5273,
+  serialized_end=7688,
   methods=[
   _descriptor.MethodDescriptor(
     name='ListContextIds',
@@ -2594,10 +2943,70 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='ListConnectionIds',
     full_name='context.ContextService.ListConnectionIds',
-    index=30,
+    index=36,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONIDLIST,
@@ -2607,7 +3016,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='ListConnections',
     full_name='context.ContextService.ListConnections',
-    index=31,
+    index=37,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONLIST,
@@ -2617,7 +3026,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnection',
     full_name='context.ContextService.GetConnection',
-    index=32,
+    index=38,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_CONNECTION,
@@ -2627,7 +3036,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetConnection',
     full_name='context.ContextService.SetConnection',
-    index=33,
+    index=39,
     containing_service=None,
     input_type=_CONNECTION,
     output_type=_CONNECTIONID,
@@ -2637,7 +3046,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='RemoveConnection',
     full_name='context.ContextService.RemoveConnection',
-    index=34,
+    index=40,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_EMPTY,
@@ -2647,7 +3056,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnectionEvents',
     full_name='context.ContextService.GetConnectionEvents',
-    index=35,
+    index=41,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_CONNECTIONEVENT,
diff --git a/src/context/proto/context_pb2_grpc.py b/src/context/proto/context_pb2_grpc.py
index 14397184e..8b30e91f3 100644
--- a/src/context/proto/context_pb2_grpc.py
+++ b/src/context/proto/context_pb2_grpc.py
@@ -164,6 +164,36 @@ class ContextServiceStub(object):
                 request_serializer=context__pb2.Empty.SerializeToString,
                 response_deserializer=context__pb2.ServiceEvent.FromString,
                 )
+        self.ListSliceIds = channel.unary_unary(
+                '/context.ContextService/ListSliceIds',
+                request_serializer=context__pb2.ContextId.SerializeToString,
+                response_deserializer=context__pb2.SliceIdList.FromString,
+                )
+        self.ListSlices = channel.unary_unary(
+                '/context.ContextService/ListSlices',
+                request_serializer=context__pb2.ContextId.SerializeToString,
+                response_deserializer=context__pb2.SliceList.FromString,
+                )
+        self.GetSlice = channel.unary_unary(
+                '/context.ContextService/GetSlice',
+                request_serializer=context__pb2.SliceId.SerializeToString,
+                response_deserializer=context__pb2.Slice.FromString,
+                )
+        self.SetSlice = channel.unary_unary(
+                '/context.ContextService/SetSlice',
+                request_serializer=context__pb2.Slice.SerializeToString,
+                response_deserializer=context__pb2.SliceId.FromString,
+                )
+        self.RemoveSlice = channel.unary_unary(
+                '/context.ContextService/RemoveSlice',
+                request_serializer=context__pb2.SliceId.SerializeToString,
+                response_deserializer=context__pb2.Empty.FromString,
+                )
+        self.GetSliceEvents = channel.unary_stream(
+                '/context.ContextService/GetSliceEvents',
+                request_serializer=context__pb2.Empty.SerializeToString,
+                response_deserializer=context__pb2.SliceEvent.FromString,
+                )
         self.ListConnectionIds = channel.unary_unary(
                 '/context.ContextService/ListConnectionIds',
                 request_serializer=context__pb2.ServiceId.SerializeToString,
@@ -379,6 +409,42 @@ class ContextServiceServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
+    def ListSliceIds(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def ListSlices(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def SetSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def RemoveSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetSliceEvents(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
     def ListConnectionIds(self, request, context):
         """Missing associated documentation comment in .proto file."""
         context.set_code(grpc.StatusCode.UNIMPLEMENTED)
@@ -568,6 +634,36 @@ def add_ContextServiceServicer_to_server(servicer, server):
                     request_deserializer=context__pb2.Empty.FromString,
                     response_serializer=context__pb2.ServiceEvent.SerializeToString,
             ),
+            'ListSliceIds': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListSliceIds,
+                    request_deserializer=context__pb2.ContextId.FromString,
+                    response_serializer=context__pb2.SliceIdList.SerializeToString,
+            ),
+            'ListSlices': grpc.unary_unary_rpc_method_handler(
+                    servicer.ListSlices,
+                    request_deserializer=context__pb2.ContextId.FromString,
+                    response_serializer=context__pb2.SliceList.SerializeToString,
+            ),
+            'GetSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.GetSlice,
+                    request_deserializer=context__pb2.SliceId.FromString,
+                    response_serializer=context__pb2.Slice.SerializeToString,
+            ),
+            'SetSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.SetSlice,
+                    request_deserializer=context__pb2.Slice.FromString,
+                    response_serializer=context__pb2.SliceId.SerializeToString,
+            ),
+            'RemoveSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.RemoveSlice,
+                    request_deserializer=context__pb2.SliceId.FromString,
+                    response_serializer=context__pb2.Empty.SerializeToString,
+            ),
+            'GetSliceEvents': grpc.unary_stream_rpc_method_handler(
+                    servicer.GetSliceEvents,
+                    request_deserializer=context__pb2.Empty.FromString,
+                    response_serializer=context__pb2.SliceEvent.SerializeToString,
+            ),
             'ListConnectionIds': grpc.unary_unary_rpc_method_handler(
                     servicer.ListConnectionIds,
                     request_deserializer=context__pb2.ServiceId.FromString,
@@ -1118,6 +1214,108 @@ class ContextService(object):
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
+    @staticmethod
+    def ListSliceIds(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListSliceIds',
+            context__pb2.ContextId.SerializeToString,
+            context__pb2.SliceIdList.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def ListSlices(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/ListSlices',
+            context__pb2.ContextId.SerializeToString,
+            context__pb2.SliceList.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/GetSlice',
+            context__pb2.SliceId.SerializeToString,
+            context__pb2.Slice.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def SetSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/SetSlice',
+            context__pb2.Slice.SerializeToString,
+            context__pb2.SliceId.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def RemoveSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/context.ContextService/RemoveSlice',
+            context__pb2.SliceId.SerializeToString,
+            context__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetSliceEvents(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_stream(request, target, '/context.ContextService/GetSliceEvents',
+            context__pb2.Empty.SerializeToString,
+            context__pb2.SliceEvent.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
     @staticmethod
     def ListConnectionIds(request,
             target,
diff --git a/src/context/service/database/RelationModels.py b/src/context/service/database/RelationModels.py
index 20e0fc450..98b077a77 100644
--- a/src/context/service/database/RelationModels.py
+++ b/src/context/service/database/RelationModels.py
@@ -21,6 +21,7 @@ from .DeviceModel import DeviceModel
 from .EndPointModel import EndPointModel
 from .LinkModel import LinkModel
 from .ServiceModel import ServiceModel
+from .SliceModel import SliceModel
 from .TopologyModel import TopologyModel
 
 LOGGER = logging.getLogger(__name__)
@@ -40,6 +41,21 @@ class ServiceEndPointModel(Model): # pylint: disable=abstract-method
     service_fk = ForeignKeyField(ServiceModel)
     endpoint_fk = ForeignKeyField(EndPointModel)
 
+class SliceEndPointModel(Model): # pylint: disable=abstract-method
+    pk = PrimaryKeyField()
+    slice_fk = ForeignKeyField(SliceModel)
+    endpoint_fk = ForeignKeyField(EndPointModel)
+
+class SliceServiceModel(Model): # pylint: disable=abstract-method
+    pk = PrimaryKeyField()
+    slice_fk = ForeignKeyField(SliceModel)
+    service_fk = ForeignKeyField(ServiceModel)
+
+class SliceSubSliceModel(Model): # pylint: disable=abstract-method
+    pk = PrimaryKeyField()
+    slice_fk = ForeignKeyField(SliceModel)
+    sub_slice_fk = ForeignKeyField(SliceModel)
+
 class TopologyDeviceModel(Model): # pylint: disable=abstract-method
     pk = PrimaryKeyField()
     topology_fk = ForeignKeyField(TopologyModel)
diff --git a/src/context/service/database/SliceModel.py b/src/context/service/database/SliceModel.py
new file mode 100644
index 000000000..5b560a948
--- /dev/null
+++ b/src/context/service/database/SliceModel.py
@@ -0,0 +1,85 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import functools, logging, operator
+from enum import Enum
+from typing import Dict, List
+from common.orm.fields.EnumeratedField import EnumeratedField
+from common.orm.fields.ForeignKeyField import ForeignKeyField
+from common.orm.fields.PrimaryKeyField import PrimaryKeyField
+from common.orm.fields.StringField import StringField
+from common.orm.model.Model import Model
+from common.orm.HighLevel import get_related_objects
+from context.proto.context_pb2 import SliceStatusEnum
+from .ConstraintModel import ConstraintsModel
+from .ContextModel import ContextModel
+from .Tools import grpc_to_enum
+
+LOGGER = logging.getLogger(__name__)
+
+class ORM_SliceStatusEnum(Enum):
+    UNDEFINED = SliceStatusEnum.SLICESTATUS_UNDEFINED
+    PLANNED   = SliceStatusEnum.SLICESTATUS_PLANNED
+    INIT      = SliceStatusEnum.SLICESTATUS_INIT
+    ACTIVE    = SliceStatusEnum.SLICESTATUS_ACTIVE
+    DEINIT    = SliceStatusEnum.SLICESTATUS_DEINIT
+
+grpc_to_enum__slice_status = functools.partial(
+    grpc_to_enum, SliceStatusEnum, ORM_SliceStatusEnum)
+
+class SliceModel(Model):
+    pk = PrimaryKeyField()
+    context_fk = ForeignKeyField(ContextModel)
+    slice_uuid = StringField(required=True, allow_empty=False)
+    slice_constraints_fk = ForeignKeyField(ConstraintsModel)
+    slice_status = EnumeratedField(ORM_SliceStatusEnum, required=True)
+
+    def dump_id(self) -> Dict:
+        context_id = ContextModel(self.database, self.context_fk).dump_id()
+        return {
+            'context_id': context_id,
+            'slice_uuid': {'uuid': self.slice_uuid},
+        }
+
+    def dump_endpoint_ids(self) -> List[Dict]:
+        from .RelationModels import SliceEndPointModel # pylint: disable=import-outside-toplevel
+        db_endpoints = get_related_objects(self, SliceEndPointModel, 'endpoint_fk')
+        return [db_endpoint.dump_id() for db_endpoint in sorted(db_endpoints, key=operator.attrgetter('pk'))]
+
+    def dump_constraints(self) -> List[Dict]:
+        return ConstraintsModel(self.database, self.slice_constraints_fk).dump()
+
+    def dump_service_ids(self) -> List[Dict]:
+        from .RelationModels import SliceServiceModel # pylint: disable=import-outside-toplevel
+        db_services = get_related_objects(self, SliceServiceModel, 'service_fk')
+        return [db_service.dump_id() for db_service in sorted(db_services, key=operator.attrgetter('pk'))]
+
+    def dump_subslice_ids(self) -> List[Dict]:
+        from .RelationModels import SliceSubSliceModel # pylint: disable=import-outside-toplevel
+        db_subslices = get_related_objects(self, SliceSubSliceModel, 'sub_slice_fk')
+        return [db_subslice.dump_id() for db_subslice in sorted(db_subslices, key=operator.attrgetter('pk'))]
+
+    def dump(   # pylint: disable=arguments-differ
+            self, include_endpoint_ids=True, include_constraints=True, include_service_ids=True,
+            include_subslice_ids=True
+        ) -> Dict:
+        result = {
+            'slice_id': self.dump_id(),
+            'slice_status': {'slice_status': self.slice_status.value},
+        }
+        if include_endpoint_ids: result['slice_endpoint_ids'] = self.dump_endpoint_ids()
+        if include_constraints: result['slice_constraints'] = self.dump_constraints()
+        if include_service_ids: result['slice_service_ids'] = self.dump_service_ids()
+        if include_subslice_ids: result['slice_subslice_ids'] = self.dump_subslice_ids()
+        return result
diff --git a/src/context/service/grpc_server/Constants.py b/src/context/service/grpc_server/Constants.py
index b9676397c..9d7c886c7 100644
--- a/src/context/service/grpc_server/Constants.py
+++ b/src/context/service/grpc_server/Constants.py
@@ -12,13 +12,14 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+TOPIC_CONNECTION = 'connection'
 TOPIC_CONTEXT    = 'context'
 TOPIC_TOPOLOGY   = 'topology'
 TOPIC_DEVICE     = 'device'
 TOPIC_LINK       = 'link'
 TOPIC_SERVICE    = 'service'
-TOPIC_CONNECTION = 'connection'
+TOPIC_SLICE      = 'slice'
 
-TOPICS = {TOPIC_CONTEXT, TOPIC_TOPOLOGY, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_CONNECTION}
+TOPICS = {TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_TOPOLOGY, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE}
 
 CONSUME_TIMEOUT = 0.5 # seconds
diff --git a/src/context/service/grpc_server/ContextServiceServicerImpl.py b/src/context/service/grpc_server/ContextServiceServicerImpl.py
index 8e4059215..9218d550f 100644
--- a/src/context/service/grpc_server/ContextServiceServicerImpl.py
+++ b/src/context/service/grpc_server/ContextServiceServicerImpl.py
@@ -24,8 +24,8 @@ from common.rpc_method_wrapper.ServiceExceptions import InvalidArgumentException
 from context.proto.context_pb2 import (
     Connection, ConnectionEvent, ConnectionId, ConnectionIdList, ConnectionList, Context, ContextEvent, ContextId,
     ContextIdList, ContextList, Device, DeviceEvent, DeviceId, DeviceIdList, DeviceList, Empty, EventTypeEnum, Link,
-    LinkEvent, LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, Topology,
-    TopologyEvent, TopologyId, TopologyIdList, TopologyList)
+    LinkEvent, LinkId, LinkIdList, LinkList, Service, ServiceEvent, ServiceId, ServiceIdList, ServiceList, Slice, SliceEvent,
+    SliceId, SliceIdList, SliceList, Topology, TopologyEvent, TopologyId, TopologyIdList, TopologyList)
 from context.proto.context_pb2_grpc import ContextServiceServicer
 from context.service.database.ConfigModel import ConfigModel, ConfigRuleModel, grpc_config_rules_to_raw, update_config
 from context.service.database.ConnectionModel import ConnectionModel, PathHopModel, PathModel, set_path
@@ -37,12 +37,13 @@ from context.service.database.EndPointModel import EndPointModel, KpiSampleTypeM
 from context.service.database.Events import notify_event
 from context.service.database.LinkModel import LinkModel
 from context.service.database.RelationModels import (
-    ConnectionSubServiceModel, LinkEndPointModel, ServiceEndPointModel, TopologyDeviceModel, TopologyLinkModel)
+    ConnectionSubServiceModel, LinkEndPointModel, ServiceEndPointModel, SliceEndPointModel, SliceServiceModel, SliceSubSliceModel, TopologyDeviceModel, TopologyLinkModel)
 from context.service.database.ServiceModel import (
     ServiceModel, grpc_to_enum__service_status, grpc_to_enum__service_type)
+from context.service.database.SliceModel import SliceModel, grpc_to_enum__slice_status
 from context.service.database.TopologyModel import TopologyModel
 from .Constants import (
-    CONSUME_TIMEOUT, TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_TOPOLOGY)
+    CONSUME_TIMEOUT, TOPIC_CONNECTION, TOPIC_CONTEXT, TOPIC_DEVICE, TOPIC_LINK, TOPIC_SERVICE, TOPIC_SLICE, TOPIC_TOPOLOGY)
 
 LOGGER = logging.getLogger(__name__)
 
@@ -54,6 +55,7 @@ METHOD_NAMES = [
     'ListDeviceIds',     'ListDevices',     'GetDevice',     'SetDevice',     'RemoveDevice',     'GetDeviceEvents',
     'ListLinkIds',       'ListLinks',       'GetLink',       'SetLink',       'RemoveLink',       'GetLinkEvents',
     'ListServiceIds',    'ListServices',    'GetService',    'SetService',    'RemoveService',    'GetServiceEvents',
+    'ListSliceIds',      'ListSlices',      'GetSlice',      'SetSlice',      'RemoveSlice',      'GetSliceEvents',
 ]
 METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
 
@@ -183,7 +185,8 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             topology_uuid = request.topology_id.topology_uuid.uuid
             str_topology_key = key_to_str([context_uuid, topology_uuid])
             result : Tuple[TopologyModel, bool] = update_or_create_object(
-                self.database, TopologyModel, str_topology_key, {'context_fk': db_context, 'topology_uuid': topology_uuid})
+                self.database, TopologyModel, str_topology_key, {
+                    'context_fk': db_context, 'topology_uuid': topology_uuid})
             db_topology,updated = result
 
             for device_id in request.device_ids:
@@ -403,7 +406,8 @@ class ContextServiceServicerImpl(ContextServiceServicer):
                     str_topology_key = key_to_str([endpoint_topology_context_uuid, endpoint_topology_uuid])
                     db_topology : TopologyModel = get_object(self.database, TopologyModel, str_topology_key)
                     str_topology_device_key = key_to_str([str_topology_key, endpoint_device_uuid], separator='--')
-                    get_object(self.database, TopologyDeviceModel, str_topology_device_key) # check device is in topology
+                    # check device is in topology
+                    get_object(self.database, TopologyDeviceModel, str_topology_device_key)
                     str_endpoint_key = key_to_str([str_endpoint_key, str_topology_key], separator=':')
 
                 db_endpoint : EndPointModel = get_object(self.database, EndPointModel, str_endpoint_key)
@@ -491,7 +495,8 @@ class ContextServiceServicerImpl(ContextServiceServicer):
                     raise InvalidArgumentException(
                         'request.service_endpoint_ids[{:d}].topology_id.context_id.context_uuid.uuid'.format(i),
                         endpoint_topology_context_uuid,
-                        ['should be == {:s}({:s})'.format('request.service_id.context_id.context_uuid.uuid', context_uuid)])
+                        ['should be == {:s}({:s})'.format(
+                            'request.service_id.context_id.context_uuid.uuid', context_uuid)])
 
             service_uuid = request.service_id.service_uuid.uuid
             str_service_key = key_to_str([context_uuid, service_uuid])
@@ -574,6 +579,148 @@ class ContextServiceServicerImpl(ContextServiceServicer):
             yield ServiceEvent(**json.loads(message.content))
 
 
+    # ----- Slice ----------------------------------------------------------------------------------------------------
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def ListSliceIds(self, request: ContextId, context : grpc.ServicerContext) -> SliceIdList:
+        with self.lock:
+            db_context : ContextModel = get_object(self.database, ContextModel, request.context_uuid.uuid)
+            db_slices : Set[SliceModel] = get_related_objects(db_context, SliceModel)
+            db_slices = sorted(db_slices, key=operator.attrgetter('pk'))
+            return SliceIdList(slice_ids=[db_slice.dump_id() for db_slice in db_slices])
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def ListSlices(self, request: ContextId, context : grpc.ServicerContext) -> SliceList:
+        with self.lock:
+            db_context : ContextModel = get_object(self.database, ContextModel, request.context_uuid.uuid)
+            db_slices : Set[SliceModel] = get_related_objects(db_context, SliceModel)
+            db_slices = sorted(db_slices, key=operator.attrgetter('pk'))
+            return SliceList(slices=[db_slice.dump() for db_slice in db_slices])
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def GetSlice(self, request: SliceId, context : grpc.ServicerContext) -> Slice:
+        with self.lock:
+            str_key = key_to_str([request.context_id.context_uuid.uuid, request.slice_uuid.uuid])
+            db_slice : SliceModel = get_object(self.database, SliceModel, str_key)
+            return Slice(**db_slice.dump(
+                include_endpoint_ids=True, include_constraints=True, include_service_ids=True,
+                include_subslice_ids=True))
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def SetSlice(self, request: Slice, context : grpc.ServicerContext) -> SliceId:
+        with self.lock:
+            context_uuid = request.slice_id.context_id.context_uuid.uuid
+            db_context : ContextModel = get_object(self.database, ContextModel, context_uuid)
+
+            for i,endpoint_id in enumerate(request.slice_endpoint_ids):
+                endpoint_topology_context_uuid = endpoint_id.topology_id.context_id.context_uuid.uuid
+                if len(endpoint_topology_context_uuid) > 0 and context_uuid != endpoint_topology_context_uuid:
+                    raise InvalidArgumentException(
+                        'request.slice_endpoint_ids[{:d}].topology_id.context_id.context_uuid.uuid'.format(i),
+                        endpoint_topology_context_uuid,
+                        ['should be == {:s}({:s})'.format(
+                            'request.slice_id.context_id.context_uuid.uuid', context_uuid)])
+
+            slice_uuid = request.slice_id.slice_uuid.uuid
+            str_slice_key = key_to_str([context_uuid, slice_uuid])
+
+            constraints_result = set_constraints(
+                self.database, str_slice_key, 'constraints', request.slice_constraints)
+            db_constraints = constraints_result[0][0]
+
+            result : Tuple[SliceModel, bool] = update_or_create_object(self.database, SliceModel, str_slice_key, {
+                'context_fk'          : db_context,
+                'slice_uuid'          : slice_uuid,
+                'slice_constraints_fk': db_constraints,
+                'slice_status'        : grpc_to_enum__slice_status(request.slice_status.slice_status),
+            })
+            db_slice, updated = result
+
+            for i,endpoint_id in enumerate(request.slice_endpoint_ids):
+                endpoint_uuid                  = endpoint_id.endpoint_uuid.uuid
+                endpoint_device_uuid           = endpoint_id.device_id.device_uuid.uuid
+                endpoint_topology_uuid         = endpoint_id.topology_id.topology_uuid.uuid
+                endpoint_topology_context_uuid = endpoint_id.topology_id.context_id.context_uuid.uuid
+
+                str_endpoint_key = key_to_str([endpoint_device_uuid, endpoint_uuid])
+                if len(endpoint_topology_context_uuid) > 0 and len(endpoint_topology_uuid) > 0:
+                    str_topology_key = key_to_str([endpoint_topology_context_uuid, endpoint_topology_uuid])
+                    str_endpoint_key = key_to_str([str_endpoint_key, str_topology_key], separator=':')
+
+                db_endpoint : EndPointModel = get_object(self.database, EndPointModel, str_endpoint_key)
+
+                str_slice_endpoint_key = key_to_str([slice_uuid, str_endpoint_key], separator='--')
+                result : Tuple[SliceEndPointModel, bool] = get_or_create_object(
+                    self.database, SliceEndPointModel, str_slice_endpoint_key, {
+                        'slice_fk': db_slice, 'endpoint_fk': db_endpoint})
+                #db_slice_endpoint, slice_endpoint_created = result
+
+            for i,service_id in enumerate(request.slice_service_ids):
+                service_uuid         = service_id.service_uuid.uuid
+                service_context_uuid = service_id.context_id.context_uuid.uuid
+                str_service_key = key_to_str([service_context_uuid, service_uuid])
+                db_service : ServiceModel = get_object(self.database, ServiceModel, str_service_key)
+
+                str_slice_service_key = key_to_str([str_slice_key, str_service_key], separator='--')
+                result : Tuple[SliceServiceModel, bool] = get_or_create_object(
+                    self.database, SliceServiceModel, str_slice_service_key, {
+                        'slice_fk': db_slice, 'service_fk': db_service})
+                #db_slice_service, slice_service_created = result
+
+            for i,subslice_id in enumerate(request.slice_subslice_ids):
+                subslice_uuid         = subslice_id.slice_uuid.uuid
+                subslice_context_uuid = subslice_id.context_id.context_uuid.uuid
+                str_subslice_key = key_to_str([subslice_context_uuid, subslice_uuid])
+                db_subslice : SliceModel = get_object(self.database, SliceModel, str_subslice_key)
+
+                str_slice_subslice_key = key_to_str([str_slice_key, str_subslice_key], separator='--')
+                result : Tuple[SliceSubSliceModel, bool] = get_or_create_object(
+                    self.database, SliceSubSliceModel, str_slice_subslice_key, {
+                        'slice_fk': db_slice, 'sub_slice_fk': db_subslice})
+                #db_slice_subslice, slice_subslice_created = result
+
+            event_type = EventTypeEnum.EVENTTYPE_UPDATE if updated else EventTypeEnum.EVENTTYPE_CREATE
+            dict_slice_id = db_slice.dump_id()
+            notify_event(self.messagebroker, TOPIC_SLICE, event_type, {'slice_id': dict_slice_id})
+            return SliceId(**dict_slice_id)
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def RemoveSlice(self, request: SliceId, context : grpc.ServicerContext) -> Empty:
+        with self.lock:
+            context_uuid = request.context_id.context_uuid.uuid
+            slice_uuid = request.slice_uuid.uuid
+            db_slice = SliceModel(self.database, key_to_str([context_uuid, slice_uuid]), auto_load=False)
+            found = db_slice.load()
+            if not found: return Empty()
+
+            dict_slice_id = db_slice.dump_id()
+
+            for db_slice_endpoint_pk,_ in db_slice.references(SliceEndPointModel):
+                SliceEndPointModel(self.database, db_slice_endpoint_pk).delete()
+
+            db_constraints = ConstraintsModel(self.database, db_slice.slice_constraints_fk)
+            for db_constraint_pk,_ in db_constraints.references(ConstraintModel):
+                ConstraintModel(self.database, db_constraint_pk).delete()
+
+            for db_slice_service_pk,_ in db_slice.references(SliceServiceModel):
+                SliceServiceModel(self.database, db_slice_service_pk).delete()
+
+            for db_slice_subslice_pk,_ in db_slice.references(SliceSubSliceModel):
+                SliceSubSliceModel(self.database, db_slice_subslice_pk).delete()
+
+            db_slice.delete()
+            db_constraints.delete()
+
+            event_type = EventTypeEnum.EVENTTYPE_REMOVE
+            notify_event(self.messagebroker, TOPIC_SLICE, event_type, {'slice_id': dict_slice_id})
+            return Empty()
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def GetSliceEvents(self, request: Empty, context : grpc.ServicerContext) -> Iterator[SliceEvent]:
+        for message in self.messagebroker.consume({TOPIC_SLICE}, consume_timeout=CONSUME_TIMEOUT):
+            yield SliceEvent(**json.loads(message.content))
+
+
     # ----- Connection -------------------------------------------------------------------------------------------------
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
diff --git a/src/context/service/rest_server/Resources.py b/src/context/service/rest_server/Resources.py
index 966c62f96..95c06d83c 100644
--- a/src/context/service/rest_server/Resources.py
+++ b/src/context/service/rest_server/Resources.py
@@ -17,7 +17,7 @@ from flask.json import jsonify
 from flask_restful import Resource
 from common.orm.Database import Database
 from common.tools.grpc.Tools import grpc_message_to_json
-from context.proto.context_pb2 import ConnectionId, ContextId, DeviceId, Empty, LinkId, ServiceId, TopologyId
+from context.proto.context_pb2 import ConnectionId, ContextId, DeviceId, Empty, LinkId, ServiceId, SliceId, TopologyId
 from context.service.grpc_server.ContextServiceServicerImpl import ContextServiceServicerImpl
 
 def format_grpc_to_json(grpc_reply):
@@ -49,6 +49,12 @@ def grpc_service_id(context_uuid, service_uuid):
         'service_uuid': {'uuid': service_uuid}
     })
 
+def grpc_slice_id(context_uuid, slice_uuid):
+    return SliceId(**{
+        'context_id': {'context_uuid': {'uuid': context_uuid}},
+        'slice_uuid': {'uuid': slice_uuid}
+    })
+
 def grpc_topology_id(context_uuid, topology_uuid):
     return TopologyId(**{
         'context_id': {'context_uuid': {'uuid': context_uuid}},
@@ -97,6 +103,18 @@ class Service(_Resource):
     def get(self, context_uuid : str, service_uuid : str):
         return format_grpc_to_json(self.servicer.GetService(grpc_service_id(context_uuid, service_uuid), None))
 
+class SliceIds(_Resource):
+    def get(self, context_uuid : str):
+        return format_grpc_to_json(self.servicer.ListSliceIds(grpc_context_id(context_uuid), None))
+
+class Slices(_Resource):
+    def get(self, context_uuid : str):
+        return format_grpc_to_json(self.servicer.ListSlices(grpc_context_id(context_uuid), None))
+
+class Slice(_Resource):
+    def get(self, context_uuid : str, slice_uuid : str):
+        return format_grpc_to_json(self.servicer.GetSlice(grpc_slice_id(context_uuid, slice_uuid), None))
+
 class DeviceIds(_Resource):
     def get(self):
         return format_grpc_to_json(self.servicer.ListDeviceIds(Empty(), None))
@@ -141,7 +159,7 @@ class DumpText(Resource):
     def get(self):
         db_entries = self.database.dump()
         num_entries = len(db_entries)
-        response = ['----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries))]
+        response = ['----- Database Dump [{:3d} entries] -------------------------'.format(num_entries)]
         for db_entry in db_entries:
             response.append('  [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
         response.append('-----------------------------------------------------------')
@@ -185,6 +203,10 @@ RESOURCES = [
     ('api.services',       Services,      '/context/<string:context_uuid>/services'),
     ('api.service',        Service,       '/context/<string:context_uuid>/service/<path:service_uuid>'),
 
+    ('api.slice_ids',      SliceIds,      '/context/<string:context_uuid>/slice_ids'),
+    ('api.slices',         Slices,        '/context/<string:context_uuid>/slices'),
+    ('api.slice',          Slice,         '/context/<string:context_uuid>/slice/<path:slice_uuid>'),
+
     ('api.device_ids',     DeviceIds,     '/device_ids'),
     ('api.devices',        Devices,       '/devices'),
     ('api.device',         Device,        '/device/<string:device_uuid>'),
diff --git a/src/dbscanserving/genproto.sh b/src/dbscanserving/genproto.sh
index d44156c2f..6c480c673 100755
--- a/src/dbscanserving/genproto.sh
+++ b/src/dbscanserving/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,14 +14,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 # building current service protos
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto dbscanserving.proto
diff --git a/src/dbscanserving/proto/dbscanserving_pb2.py b/src/dbscanserving/proto/dbscanserving_pb2.py
index b5e464db4..f2d6c37c7 100644
--- a/src/dbscanserving/proto/dbscanserving_pb2.py
+++ b/src/dbscanserving/proto/dbscanserving_pb2.py
@@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x13\x64\x62scanserving.proto\x12\rdbscanserving\"\x1a\n\x06Sample\x12\x10\n\x08\x66\x65\x61tures\x18\x01 \x03(\x02\"\xd6\x01\n\x10\x44\x65tectionRequest\x12\x0b\n\x03\x65ps\x18\x01 \x01(\x02\x12\x13\n\x0bmin_samples\x18\x02 \x01(\x05\x12%\n\x06metric\x18\x03 \x01(\x0e\x32\x15.dbscanserving.Metric\x12\x13\n\x0bnum_samples\x18\x04 \x01(\x05\x12\x14\n\x0cnum_features\x18\x05 \x01(\x05\x12&\n\x07samples\x18\x06 \x03(\x0b\x32\x15.dbscanserving.Sample\x12\x17\n\nidentifier\x18\x07 \x01(\x05H\x00\x88\x01\x01\x42\r\n\x0b_identifier\",\n\x11\x44\x65tectionResponse\x12\x17\n\x0f\x63luster_indices\x18\x01 \x03(\x05*\x17\n\x06Metric\x12\r\n\tEUCLIDEAN\x10\x00\x32W\n\x08\x44\x65tector\x12K\n\x06\x44\x65tect\x12\x1f.dbscanserving.DetectionRequest\x1a .dbscanserving.DetectionResponseb\x06proto3'
+  serialized_pb=b'\n\x13\x64\x62scanserving.proto\x12\rdbscanserving\"\x1a\n\x06Sample\x12\x10\n\x08\x66\x65\x61tures\x18\x01 \x03(\x02\"\xc2\x01\n\x10\x44\x65tectionRequest\x12\x0b\n\x03\x65ps\x18\x01 \x01(\x02\x12\x13\n\x0bmin_samples\x18\x02 \x01(\x05\x12%\n\x06metric\x18\x03 \x01(\x0e\x32\x15.dbscanserving.Metric\x12\x13\n\x0bnum_samples\x18\x04 \x01(\x05\x12\x14\n\x0cnum_features\x18\x05 \x01(\x05\x12&\n\x07samples\x18\x06 \x03(\x0b\x32\x15.dbscanserving.Sample\x12\x12\n\nidentifier\x18\x07 \x01(\x05\",\n\x11\x44\x65tectionResponse\x12\x17\n\x0f\x63luster_indices\x18\x01 \x03(\x05*\x17\n\x06Metric\x12\r\n\tEUCLIDEAN\x10\x00\x32W\n\x08\x44\x65tector\x12K\n\x06\x44\x65tect\x12\x1f.dbscanserving.DetectionRequest\x1a .dbscanserving.DetectionResponseb\x06proto3'
 )
 
 _METRIC = _descriptor.EnumDescriptor(
@@ -38,8 +38,8 @@ _METRIC = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=329,
-  serialized_end=352,
+  serialized_start=309,
+  serialized_end=332,
 )
 _sym_db.RegisterEnumDescriptor(_METRIC)
 
@@ -148,14 +148,9 @@ _DETECTIONREQUEST = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_identifier', full_name='dbscanserving.DetectionRequest._identifier',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
   ],
   serialized_start=67,
-  serialized_end=281,
+  serialized_end=261,
 )
 
 
@@ -186,15 +181,12 @@ _DETECTIONRESPONSE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=283,
-  serialized_end=327,
+  serialized_start=263,
+  serialized_end=307,
 )
 
 _DETECTIONREQUEST.fields_by_name['metric'].enum_type = _METRIC
 _DETECTIONREQUEST.fields_by_name['samples'].message_type = _SAMPLE
-_DETECTIONREQUEST.oneofs_by_name['_identifier'].fields.append(
-  _DETECTIONREQUEST.fields_by_name['identifier'])
-_DETECTIONREQUEST.fields_by_name['identifier'].containing_oneof = _DETECTIONREQUEST.oneofs_by_name['_identifier']
 DESCRIPTOR.message_types_by_name['Sample'] = _SAMPLE
 DESCRIPTOR.message_types_by_name['DetectionRequest'] = _DETECTIONREQUEST
 DESCRIPTOR.message_types_by_name['DetectionResponse'] = _DETECTIONRESPONSE
@@ -231,8 +223,8 @@ _DETECTOR = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=354,
-  serialized_end=441,
+  serialized_start=334,
+  serialized_end=421,
   methods=[
   _descriptor.MethodDescriptor(
     name='Detect',
diff --git a/src/device/genproto.sh b/src/device/genproto.sh
index 31632fb89..49b1d10ad 100755
--- a/src/device/genproto.sh
+++ b/src/device/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,14 +14,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto device.proto
diff --git a/src/device/proto/context_pb2.py b/src/device/proto/context_pb2.py
index 68602b16f..50d501d3a 100644
--- a/src/device/proto/context_pb2.py
+++ b/src/device/proto/context_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xad\x10\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
   ,
   dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
 
@@ -55,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3703,
-  serialized_end=3809,
+  serialized_start=4310,
+  serialized_end=4416,
 )
 _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
 
@@ -101,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3812,
-  serialized_end=4009,
+  serialized_start=4419,
+  serialized_end=4616,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
 
@@ -132,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4012,
-  serialized_end=4155,
+  serialized_start=4619,
+  serialized_end=4762,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
 
@@ -168,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4158,
-  serialized_end=4287,
+  serialized_start=4765,
+  serialized_end=4894,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
 
@@ -204,12 +204,53 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4290,
-  serialized_end=4426,
+  serialized_start=4897,
+  serialized_end=5033,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
 
 ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
 _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   name='ConfigActionEnum',
   full_name='context.ConfigActionEnum',
@@ -235,8 +276,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4428,
-  serialized_end=4521,
+  serialized_start=5177,
+  serialized_end=5270,
 )
 _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
 
@@ -262,6 +303,11 @@ SERVICESTATUS_UNDEFINED = 0
 SERVICESTATUS_PLANNED = 1
 SERVICESTATUS_ACTIVE = 2
 SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
 CONFIGACTION_UNDEFINED = 0
 CONFIGACTION_SET = 1
 CONFIGACTION_DELETE = 2
@@ -1421,6 +1467,247 @@ _SERVICEEVENT = _descriptor.Descriptor(
 )
 
 
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
 _CONNECTIONID = _descriptor.Descriptor(
   name='ConnectionId',
   full_name='context.ConnectionId',
@@ -1448,8 +1735,8 @@ _CONNECTIONID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2604,
-  serialized_end=2658,
+  serialized_start=3211,
+  serialized_end=3265,
 )
 
 
@@ -1501,8 +1788,8 @@ _CONNECTION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2661,
-  serialized_end=2857,
+  serialized_start=3268,
+  serialized_end=3464,
 )
 
 
@@ -1533,8 +1820,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2859,
-  serialized_end=2924,
+  serialized_start=3466,
+  serialized_end=3531,
 )
 
 
@@ -1565,8 +1852,8 @@ _CONNECTIONLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2926,
-  serialized_end=2984,
+  serialized_start=3533,
+  serialized_end=3591,
 )
 
 
@@ -1604,8 +1891,8 @@ _CONNECTIONEVENT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2986,
-  serialized_end=3080,
+  serialized_start=3593,
+  serialized_end=3687,
 )
 
 
@@ -1650,8 +1937,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3083,
-  serialized_end=3213,
+  serialized_start=3690,
+  serialized_end=3820,
 )
 
 
@@ -1696,8 +1983,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3216,
-  serialized_end=3350,
+  serialized_start=3823,
+  serialized_end=3957,
 )
 
 
@@ -1742,8 +2029,8 @@ _CONFIGRULE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3352,
-  serialized_end=3453,
+  serialized_start=3959,
+  serialized_end=4060,
 )
 
 
@@ -1781,8 +2068,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3455,
-  serialized_end=3518,
+  serialized_start=4062,
+  serialized_end=4125,
 )
 
 
@@ -1827,8 +2114,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3520,
-  serialized_end=3614,
+  serialized_start=4127,
+  serialized_end=4221,
 )
 
 
@@ -1866,8 +2153,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3616,
-  serialized_end=3701,
+  serialized_start=4223,
+  serialized_end=4308,
 )
 
 _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
@@ -1921,6 +2208,19 @@ _SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
 _SERVICELIST.fields_by_name['services'].message_type = _SERVICE
 _SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
 _SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
 _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
 _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
 _CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
@@ -1969,6 +2269,12 @@ DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
 DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
 DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
 DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
 DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
 DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
 DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
@@ -1985,6 +2291,7 @@ DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
 DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
 DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
 DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
 DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -2205,6 +2512,48 @@ ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_messag
   })
 _sym_db.RegisterMessage(ServiceEvent)
 
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
 ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
   'DESCRIPTOR' : _CONNECTIONID,
   '__module__' : 'context_pb2'
@@ -2291,8 +2640,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=4524,
-  serialized_end=6617,
+  serialized_start=5273,
+  serialized_end=7688,
   methods=[
   _descriptor.MethodDescriptor(
     name='ListContextIds',
@@ -2594,10 +2943,70 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='ListConnectionIds',
     full_name='context.ContextService.ListConnectionIds',
-    index=30,
+    index=36,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONIDLIST,
@@ -2607,7 +3016,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='ListConnections',
     full_name='context.ContextService.ListConnections',
-    index=31,
+    index=37,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONLIST,
@@ -2617,7 +3026,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnection',
     full_name='context.ContextService.GetConnection',
-    index=32,
+    index=38,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_CONNECTION,
@@ -2627,7 +3036,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetConnection',
     full_name='context.ContextService.SetConnection',
-    index=33,
+    index=39,
     containing_service=None,
     input_type=_CONNECTION,
     output_type=_CONNECTIONID,
@@ -2637,7 +3046,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='RemoveConnection',
     full_name='context.ContextService.RemoveConnection',
-    index=34,
+    index=40,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_EMPTY,
@@ -2647,7 +3056,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnectionEvents',
     full_name='context.ContextService.GetConnectionEvents',
-    index=35,
+    index=41,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_CONNECTIONEVENT,
diff --git a/src/interdomain/.gitlab-ci.yml b/src/interdomain/.gitlab-ci.yml
new file mode 100644
index 000000000..f4dd49fd0
--- /dev/null
+++ b/src/interdomain/.gitlab-ci.yml
@@ -0,0 +1,102 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Build, tag and push the Docker image to the GitLab registry
+build service:
+  variables:
+    IMAGE_NAME: 'service' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: build
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+  script:
+    - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile ./src/
+    - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+  after_script:
+    - docker images --filter="dangling=true" --quiet | xargs -r docker rmi
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' 
+    - changes:
+      - src/$IMAGE_NAME/**/*.{py,in,yml}
+      - src/$IMAGE_NAME/Dockerfile
+      - src/$IMAGE_NAME/tests/*.py
+      - manifests/${IMAGE_NAME}service.yaml
+      - .gitlab-ci.yml
+
+# Apply unit test to the component
+unit test service:
+  variables:
+    IMAGE_NAME: 'service' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: unit_test
+  needs:
+    - build service
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - if docker network list | grep teraflowbridge; then echo "teraflowbridge is already created"; else docker network create -d bridge teraflowbridge; fi
+    - if docker container ls | grep $IMAGE_NAME; then docker rm -f $IMAGE_NAME; else echo "$IMAGE_NAME image is not in the system"; fi
+  script:
+    - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+    - docker run --name $IMAGE_NAME -d -p 3030:3030 -v "$PWD/src/$IMAGE_NAME/tests:/opt/results" --network=teraflowbridge $CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG
+    - sleep 5
+    - docker ps -a
+    - docker logs $IMAGE_NAME
+    - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml; coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml; coverage report --include='${IMAGE_NAME}/*' --show-missing"
+  coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
+  after_script:
+    - docker rm -f $IMAGE_NAME
+    - docker network rm teraflowbridge
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' 
+    - changes:
+      - src/$IMAGE_NAME/**/*.{py,in,yml}
+      - src/$IMAGE_NAME/Dockerfile
+      - src/$IMAGE_NAME/tests/*.py
+      - src/$IMAGE_NAME/tests/Dockerfile
+      - manifests/${IMAGE_NAME}service.yaml
+      - .gitlab-ci.yml
+  artifacts:
+      when: always
+      reports:
+        junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
+        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+
+# Deployment of the service in Kubernetes Cluster
+deploy service:
+  variables:
+    IMAGE_NAME: 'service' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: deploy
+  needs:
+    - unit test service
+    # - integ_test execute
+  script:
+    - 'sed -i "s/$IMAGE_NAME:.*/$IMAGE_NAME:$IMAGE_TAG/" manifests/${IMAGE_NAME}service.yaml'
+    - kubectl version
+    - kubectl get all
+    - kubectl apply -f "manifests/${IMAGE_NAME}service.yaml"
+    - kubectl get all
+  # environment:
+  #   name: test
+  #   url: https://example.com
+  #   kubernetes:
+  #     namespace: test
+  rules:
+    - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
+      when: manual    
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
+      when: manual
diff --git a/src/interdomain/Config.py b/src/interdomain/Config.py
new file mode 100644
index 000000000..ee5cd0411
--- /dev/null
+++ b/src/interdomain/Config.py
@@ -0,0 +1,33 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging
+
+# General settings
+LOG_LEVEL = logging.WARNING
+
+# gRPC settings
+GRPC_SERVICE_PORT = 10010
+GRPC_MAX_WORKERS  = 10
+GRPC_GRACE_PERIOD = 60
+
+# Prometheus settings
+METRICS_PORT = 9192
+
+# Dependency micro-service connection settings
+CONTEXT_SERVICE_HOST = '127.0.0.1'
+CONTEXT_SERVICE_PORT = 1010
+
+SLICE_SERVICE_HOST = '127.0.0.1'
+SLICE_SERVICE_PORT = 4040
diff --git a/src/interdomain/Dockerfile b/src/interdomain/Dockerfile
new file mode 100644
index 000000000..35c7dbeba
--- /dev/null
+++ b/src/interdomain/Dockerfile
@@ -0,0 +1,54 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+FROM python:3-slim
+
+# Install dependencies
+RUN apt-get --yes --quiet --quiet update && \
+    apt-get --yes --quiet --quiet install wget g++ && \
+    rm -rf /var/lib/apt/lists/*
+
+# Set Python to show logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# Download the gRPC health probe
+RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \
+    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
+    chmod +x /bin/grpc_health_probe
+
+# Get generic Python packages
+RUN python3 -m pip install --upgrade pip setuptools wheel pip-tools
+
+# Set working directory
+WORKDIR /var/teraflow
+
+# Create module sub-folders
+RUN mkdir -p /var/teraflow/interdomain
+
+# Get Python packages per module
+COPY interdomain/requirements.in interdomain/requirements.in
+RUN pip-compile --output-file=interdomain/requirements.txt interdomain/requirements.in
+RUN python3 -m pip install -r interdomain/requirements.txt
+
+# Add files into working directory
+COPY common/. common
+COPY context/. context
+COPY device/. device
+COPY interdomain/. interdomain
+COPY monitoring/. monitoring
+COPY service/. service
+COPY slice/. slice
+
+# Start interdomain service
+ENTRYPOINT ["python", "-m", "interdomain.service"]
diff --git a/src/interdomain/__init__.py b/src/interdomain/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/interdomain/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/interdomain/client/InterdomainClient.py b/src/interdomain/client/InterdomainClient.py
new file mode 100644
index 000000000..345dfa3ec
--- /dev/null
+++ b/src/interdomain/client/InterdomainClient.py
@@ -0,0 +1,77 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from common.tools.client.RetryDecorator import retry, delay_exponential
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from interdomain.proto.context_pb2 import AuthenticationResult, Slice, SliceId, SliceStatus, TeraFlowController
+from interdomain.proto.interdomain_pb2_grpc import InterdomainServiceStub
+
+LOGGER = logging.getLogger(__name__)
+MAX_RETRIES = 15
+DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
+RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
+
+class InterdomainClient:
+    def __init__(self, address, port):
+        self.endpoint = '{:s}:{:s}'.format(str(address), str(port))
+        LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint))
+        self.channel = None
+        self.stub = None
+        self.connect()
+        LOGGER.debug('Channel created')
+
+    def connect(self):
+        self.channel = grpc.insecure_channel(self.endpoint)
+        self.stub = InterdomainServiceStub(self.channel)
+
+    def close(self):
+        if self.channel is not None: self.channel.close()
+        self.channel = None
+        self.stub = None
+
+    @RETRY_DECORATOR
+    def RequestSlice(self, request : Slice) -> SliceId:
+        LOGGER.debug('RequestSlice request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.RequestSlice(request)
+        LOGGER.debug('RequestSlice result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def Authenticate(self, request : TeraFlowController) -> AuthenticationResult:
+        LOGGER.debug('Authenticate request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.Authenticate(request)
+        LOGGER.debug('Authenticate result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def LookUpSlice(self, request : Slice) -> SliceId:
+        LOGGER.debug('LookUpSlice request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.LookUpSlice(request)
+        LOGGER.debug('LookUpSlice result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def OrderSliceFromCatalog(self, request : Slice) -> SliceStatus:
+        LOGGER.debug('OrderSliceFromCatalog request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.OrderSliceFromCatalog(request)
+        LOGGER.debug('OrderSliceFromCatalog result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def CreateSliceAndAddToCatalog(self, request : Slice) -> SliceStatus:
+        LOGGER.debug('CreateSliceAndAddToCatalog request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.CreateSliceAndAddToCatalog(request)
+        LOGGER.debug('CreateSliceAndAddToCatalog result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
diff --git a/src/interdomain/client/__init__.py b/src/interdomain/client/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/interdomain/client/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/interdomain/genproto.sh b/src/interdomain/genproto.sh
new file mode 100755
index 000000000..908b7aed6
--- /dev/null
+++ b/src/interdomain/genproto.sh
@@ -0,0 +1,52 @@
+#!/bin/bash -eu
+#
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+rm -rf proto/*.py
+rm -rf proto/__pycache__
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
+
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto interdomain.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto slice.proto
+
+rm proto/context_pb2_grpc.py
+rm proto/kpi_sample_types_pb2_grpc.py
+rm proto/slice_pb2_grpc.py
+
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/interdomain_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/interdomain_pb2_grpc.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/slice_pb2.py
diff --git a/src/interdomain/proto/__init__.py b/src/interdomain/proto/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/interdomain/proto/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/interdomain/proto/context_pb2.py b/src/interdomain/proto/context_pb2.py
new file mode 100644
index 000000000..50d501d3a
--- /dev/null
+++ b/src/interdomain/proto/context_pb2.py
@@ -0,0 +1,3071 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: context.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import kpi_sample_types_pb2 as kpi__sample__types__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='context.proto',
+  package='context',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  ,
+  dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
+
+_EVENTTYPEENUM = _descriptor.EnumDescriptor(
+  name='EventTypeEnum',
+  full_name='context.EventTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_CREATE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UPDATE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_REMOVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4310,
+  serialized_end=4416,
+)
+_sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
+
+EventTypeEnum = enum_type_wrapper.EnumTypeWrapper(_EVENTTYPEENUM)
+_DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
+  name='DeviceDriverEnum',
+  full_name='context.DeviceDriverEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_OPENCONFIG', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_TRANSPORT_API', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_P4', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_IETF_NETWORK_TOPOLOGY', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_ONF_TR_352', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4419,
+  serialized_end=4616,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
+
+DeviceDriverEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEDRIVERENUM)
+_DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
+  name='DeviceOperationalStatusEnum',
+  full_name='context.DeviceOperationalStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_DISABLED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_ENABLED', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4619,
+  serialized_end=4762,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
+
+DeviceOperationalStatusEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEOPERATIONALSTATUSENUM)
+_SERVICETYPEENUM = _descriptor.EnumDescriptor(
+  name='ServiceTypeEnum',
+  full_name='context.ServiceTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L3NM', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L2NM', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_TAPI_CONNECTIVITY_SERVICE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4765,
+  serialized_end=4894,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
+
+ServiceTypeEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPEENUM)
+_SERVICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='ServiceStatusEnum',
+  full_name='context.ServiceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_ACTIVE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PENDING_REMOVAL', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4897,
+  serialized_end=5033,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
+
+ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
+_CONFIGACTIONENUM = _descriptor.EnumDescriptor(
+  name='ConfigActionEnum',
+  full_name='context.ConfigActionEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_SET', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_DELETE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5177,
+  serialized_end=5270,
+)
+_sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
+
+ConfigActionEnum = enum_type_wrapper.EnumTypeWrapper(_CONFIGACTIONENUM)
+EVENTTYPE_UNDEFINED = 0
+EVENTTYPE_CREATE = 1
+EVENTTYPE_UPDATE = 2
+EVENTTYPE_REMOVE = 3
+DEVICEDRIVER_UNDEFINED = 0
+DEVICEDRIVER_OPENCONFIG = 1
+DEVICEDRIVER_TRANSPORT_API = 2
+DEVICEDRIVER_P4 = 3
+DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4
+DEVICEDRIVER_ONF_TR_352 = 5
+DEVICEOPERATIONALSTATUS_UNDEFINED = 0
+DEVICEOPERATIONALSTATUS_DISABLED = 1
+DEVICEOPERATIONALSTATUS_ENABLED = 2
+SERVICETYPE_UNKNOWN = 0
+SERVICETYPE_L3NM = 1
+SERVICETYPE_L2NM = 2
+SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3
+SERVICESTATUS_UNDEFINED = 0
+SERVICESTATUS_PLANNED = 1
+SERVICESTATUS_ACTIVE = 2
+SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
+CONFIGACTION_UNDEFINED = 0
+CONFIGACTION_SET = 1
+CONFIGACTION_DELETE = 2
+
+
+
+_EMPTY = _descriptor.Descriptor(
+  name='Empty',
+  full_name='context.Empty',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=50,
+  serialized_end=57,
+)
+
+
+_UUID = _descriptor.Descriptor(
+  name='Uuid',
+  full_name='context.Uuid',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='uuid', full_name='context.Uuid.uuid', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=59,
+  serialized_end=79,
+)
+
+
+_EVENT = _descriptor.Descriptor(
+  name='Event',
+  full_name='context.Event',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='context.Event.timestamp', index=0,
+      number=1, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='event_type', full_name='context.Event.event_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=81,
+  serialized_end=151,
+)
+
+
+_CONTEXTID = _descriptor.Descriptor(
+  name='ContextId',
+  full_name='context.ContextId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_uuid', full_name='context.ContextId.context_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=153,
+  serialized_end=201,
+)
+
+
+_CONTEXT = _descriptor.Descriptor(
+  name='Context',
+  full_name='context.Context',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.Context.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.Context.topology_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.Context.service_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='controller', full_name='context.Context.controller', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=204,
+  serialized_end=386,
+)
+
+
+_CONTEXTIDLIST = _descriptor.Descriptor(
+  name='ContextIdList',
+  full_name='context.ContextIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_ids', full_name='context.ContextIdList.context_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=388,
+  serialized_end=444,
+)
+
+
+_CONTEXTLIST = _descriptor.Descriptor(
+  name='ContextList',
+  full_name='context.ContextList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contexts', full_name='context.ContextList.contexts', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=446,
+  serialized_end=495,
+)
+
+
+_CONTEXTEVENT = _descriptor.Descriptor(
+  name='ContextEvent',
+  full_name='context.ContextEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ContextEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ContextEvent.context_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=497,
+  serialized_end=582,
+)
+
+
+_TOPOLOGYID = _descriptor.Descriptor(
+  name='TopologyId',
+  full_name='context.TopologyId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TopologyId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_uuid', full_name='context.TopologyId.topology_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=584,
+  serialized_end=674,
+)
+
+
+_TOPOLOGY = _descriptor.Descriptor(
+  name='Topology',
+  full_name='context.Topology',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.Topology.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.Topology.device_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.Topology.link_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=676,
+  serialized_end=802,
+)
+
+
+_TOPOLOGYIDLIST = _descriptor.Descriptor(
+  name='TopologyIdList',
+  full_name='context.TopologyIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.TopologyIdList.topology_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=804,
+  serialized_end=863,
+)
+
+
+_TOPOLOGYLIST = _descriptor.Descriptor(
+  name='TopologyList',
+  full_name='context.TopologyList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topologies', full_name='context.TopologyList.topologies', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=865,
+  serialized_end=918,
+)
+
+
+_TOPOLOGYEVENT = _descriptor.Descriptor(
+  name='TopologyEvent',
+  full_name='context.TopologyEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.TopologyEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.TopologyEvent.topology_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=920,
+  serialized_end=1008,
+)
+
+
+_DEVICEID = _descriptor.Descriptor(
+  name='DeviceId',
+  full_name='context.DeviceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_uuid', full_name='context.DeviceId.device_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1010,
+  serialized_end=1056,
+)
+
+
+_DEVICE = _descriptor.Descriptor(
+  name='Device',
+  full_name='context.Device',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.Device.device_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_type', full_name='context.Device.device_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_config', full_name='context.Device.device_config', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_operational_status', full_name='context.Device.device_operational_status', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_drivers', full_name='context.Device.device_drivers', index=4,
+      number=5, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_endpoints', full_name='context.Device.device_endpoints', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1059,
+  serialized_end=1341,
+)
+
+
+_DEVICECONFIG = _descriptor.Descriptor(
+  name='DeviceConfig',
+  full_name='context.DeviceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.DeviceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1343,
+  serialized_end=1400,
+)
+
+
+_DEVICEIDLIST = _descriptor.Descriptor(
+  name='DeviceIdList',
+  full_name='context.DeviceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.DeviceIdList.device_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1402,
+  serialized_end=1455,
+)
+
+
+_DEVICELIST = _descriptor.Descriptor(
+  name='DeviceList',
+  full_name='context.DeviceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='devices', full_name='context.DeviceList.devices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1457,
+  serialized_end=1503,
+)
+
+
+_DEVICEEVENT = _descriptor.Descriptor(
+  name='DeviceEvent',
+  full_name='context.DeviceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.DeviceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.DeviceEvent.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1505,
+  serialized_end=1587,
+)
+
+
+_LINKID = _descriptor.Descriptor(
+  name='LinkId',
+  full_name='context.LinkId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_uuid', full_name='context.LinkId.link_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1589,
+  serialized_end=1631,
+)
+
+
+_LINK = _descriptor.Descriptor(
+  name='Link',
+  full_name='context.Link',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.Link.link_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_endpoint_ids', full_name='context.Link.link_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1633,
+  serialized_end=1721,
+)
+
+
+_LINKIDLIST = _descriptor.Descriptor(
+  name='LinkIdList',
+  full_name='context.LinkIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.LinkIdList.link_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1723,
+  serialized_end=1770,
+)
+
+
+_LINKLIST = _descriptor.Descriptor(
+  name='LinkList',
+  full_name='context.LinkList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='links', full_name='context.LinkList.links', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1772,
+  serialized_end=1812,
+)
+
+
+_LINKEVENT = _descriptor.Descriptor(
+  name='LinkEvent',
+  full_name='context.LinkEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.LinkEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.LinkEvent.link_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1814,
+  serialized_end=1890,
+)
+
+
+_SERVICEID = _descriptor.Descriptor(
+  name='ServiceId',
+  full_name='context.ServiceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ServiceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_uuid', full_name='context.ServiceId.service_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1892,
+  serialized_end=1980,
+)
+
+
+_SERVICE = _descriptor.Descriptor(
+  name='Service',
+  full_name='context.Service',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Service.service_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_type', full_name='context.Service.service_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_endpoint_ids', full_name='context.Service.service_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_constraints', full_name='context.Service.service_constraints', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.Service.service_status', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_config', full_name='context.Service.service_config', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1983,
+  serialized_end=2277,
+)
+
+
+_SERVICESTATUS = _descriptor.Descriptor(
+  name='ServiceStatus',
+  full_name='context.ServiceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.ServiceStatus.service_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2279,
+  serialized_end=2346,
+)
+
+
+_SERVICECONFIG = _descriptor.Descriptor(
+  name='ServiceConfig',
+  full_name='context.ServiceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.ServiceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2348,
+  serialized_end=2406,
+)
+
+
+_SERVICEIDLIST = _descriptor.Descriptor(
+  name='ServiceIdList',
+  full_name='context.ServiceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.ServiceIdList.service_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2408,
+  serialized_end=2464,
+)
+
+
+_SERVICELIST = _descriptor.Descriptor(
+  name='ServiceList',
+  full_name='context.ServiceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='services', full_name='context.ServiceList.services', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2466,
+  serialized_end=2515,
+)
+
+
+_SERVICEEVENT = _descriptor.Descriptor(
+  name='ServiceEvent',
+  full_name='context.ServiceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ServiceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.ServiceEvent.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2517,
+  serialized_end=2602,
+)
+
+
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
+_CONNECTIONID = _descriptor.Descriptor(
+  name='ConnectionId',
+  full_name='context.ConnectionId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_uuid', full_name='context.ConnectionId.connection_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3211,
+  serialized_end=3265,
+)
+
+
+_CONNECTION = _descriptor.Descriptor(
+  name='Connection',
+  full_name='context.Connection',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.Connection.connection_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Connection.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='path_hops_endpoint_ids', full_name='context.Connection.path_hops_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='sub_service_ids', full_name='context.Connection.sub_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3268,
+  serialized_end=3464,
+)
+
+
+_CONNECTIONIDLIST = _descriptor.Descriptor(
+  name='ConnectionIdList',
+  full_name='context.ConnectionIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_ids', full_name='context.ConnectionIdList.connection_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3466,
+  serialized_end=3531,
+)
+
+
+_CONNECTIONLIST = _descriptor.Descriptor(
+  name='ConnectionList',
+  full_name='context.ConnectionList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connections', full_name='context.ConnectionList.connections', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3533,
+  serialized_end=3591,
+)
+
+
+_CONNECTIONEVENT = _descriptor.Descriptor(
+  name='ConnectionEvent',
+  full_name='context.ConnectionEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ConnectionEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.ConnectionEvent.connection_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3593,
+  serialized_end=3687,
+)
+
+
+_ENDPOINTID = _descriptor.Descriptor(
+  name='EndPointId',
+  full_name='context.EndPointId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.EndPointId.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.EndPointId.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_uuid', full_name='context.EndPointId.endpoint_uuid', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3690,
+  serialized_end=3820,
+)
+
+
+_ENDPOINT = _descriptor.Descriptor(
+  name='EndPoint',
+  full_name='context.EndPoint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='endpoint_id', full_name='context.EndPoint.endpoint_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_type', full_name='context.EndPoint.endpoint_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='kpi_sample_types', full_name='context.EndPoint.kpi_sample_types', index=2,
+      number=3, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3823,
+  serialized_end=3957,
+)
+
+
+_CONFIGRULE = _descriptor.Descriptor(
+  name='ConfigRule',
+  full_name='context.ConfigRule',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='action', full_name='context.ConfigRule.action', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_key', full_name='context.ConfigRule.resource_key', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_value', full_name='context.ConfigRule.resource_value', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3959,
+  serialized_end=4060,
+)
+
+
+_CONSTRAINT = _descriptor.Descriptor(
+  name='Constraint',
+  full_name='context.Constraint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='constraint_type', full_name='context.Constraint.constraint_type', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='constraint_value', full_name='context.Constraint.constraint_value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4062,
+  serialized_end=4125,
+)
+
+
+_TERAFLOWCONTROLLER = _descriptor.Descriptor(
+  name='TeraFlowController',
+  full_name='context.TeraFlowController',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TeraFlowController.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='ip_address', full_name='context.TeraFlowController.ip_address', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='port', full_name='context.TeraFlowController.port', index=2,
+      number=3, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4127,
+  serialized_end=4221,
+)
+
+
+_AUTHENTICATIONRESULT = _descriptor.Descriptor(
+  name='AuthenticationResult',
+  full_name='context.AuthenticationResult',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.AuthenticationResult.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='authenticated', full_name='context.AuthenticationResult.authenticated', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4223,
+  serialized_end=4308,
+)
+
+_EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
+_CONTEXTID.fields_by_name['context_uuid'].message_type = _UUID
+_CONTEXT.fields_by_name['context_id'].message_type = _CONTEXTID
+_CONTEXT.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_CONTEXT.fields_by_name['service_ids'].message_type = _SERVICEID
+_CONTEXT.fields_by_name['controller'].message_type = _TERAFLOWCONTROLLER
+_CONTEXTIDLIST.fields_by_name['context_ids'].message_type = _CONTEXTID
+_CONTEXTLIST.fields_by_name['contexts'].message_type = _CONTEXT
+_CONTEXTEVENT.fields_by_name['event'].message_type = _EVENT
+_CONTEXTEVENT.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['topology_uuid'].message_type = _UUID
+_TOPOLOGY.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_TOPOLOGY.fields_by_name['device_ids'].message_type = _DEVICEID
+_TOPOLOGY.fields_by_name['link_ids'].message_type = _LINKID
+_TOPOLOGYIDLIST.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_TOPOLOGYLIST.fields_by_name['topologies'].message_type = _TOPOLOGY
+_TOPOLOGYEVENT.fields_by_name['event'].message_type = _EVENT
+_TOPOLOGYEVENT.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_DEVICEID.fields_by_name['device_uuid'].message_type = _UUID
+_DEVICE.fields_by_name['device_id'].message_type = _DEVICEID
+_DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG
+_DEVICE.fields_by_name['device_operational_status'].enum_type = _DEVICEOPERATIONALSTATUSENUM
+_DEVICE.fields_by_name['device_drivers'].enum_type = _DEVICEDRIVERENUM
+_DEVICE.fields_by_name['device_endpoints'].message_type = _ENDPOINT
+_DEVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_DEVICEIDLIST.fields_by_name['device_ids'].message_type = _DEVICEID
+_DEVICELIST.fields_by_name['devices'].message_type = _DEVICE
+_DEVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_DEVICEEVENT.fields_by_name['device_id'].message_type = _DEVICEID
+_LINKID.fields_by_name['link_uuid'].message_type = _UUID
+_LINK.fields_by_name['link_id'].message_type = _LINKID
+_LINK.fields_by_name['link_endpoint_ids'].message_type = _ENDPOINTID
+_LINKIDLIST.fields_by_name['link_ids'].message_type = _LINKID
+_LINKLIST.fields_by_name['links'].message_type = _LINK
+_LINKEVENT.fields_by_name['event'].message_type = _EVENT
+_LINKEVENT.fields_by_name['link_id'].message_type = _LINKID
+_SERVICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SERVICEID.fields_by_name['service_uuid'].message_type = _UUID
+_SERVICE.fields_by_name['service_id'].message_type = _SERVICEID
+_SERVICE.fields_by_name['service_type'].enum_type = _SERVICETYPEENUM
+_SERVICE.fields_by_name['service_endpoint_ids'].message_type = _ENDPOINTID
+_SERVICE.fields_by_name['service_constraints'].message_type = _CONSTRAINT
+_SERVICE.fields_by_name['service_status'].message_type = _SERVICESTATUS
+_SERVICE.fields_by_name['service_config'].message_type = _SERVICECONFIG
+_SERVICESTATUS.fields_by_name['service_status'].enum_type = _SERVICESTATUSENUM
+_SERVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
+_SERVICELIST.fields_by_name['services'].message_type = _SERVICE
+_SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
+_CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
+_CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
+_CONNECTION.fields_by_name['path_hops_endpoint_ids'].message_type = _ENDPOINTID
+_CONNECTION.fields_by_name['sub_service_ids'].message_type = _SERVICEID
+_CONNECTIONIDLIST.fields_by_name['connection_ids'].message_type = _CONNECTIONID
+_CONNECTIONLIST.fields_by_name['connections'].message_type = _CONNECTION
+_CONNECTIONEVENT.fields_by_name['event'].message_type = _EVENT
+_CONNECTIONEVENT.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_ENDPOINTID.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID
+_ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID
+_ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID
+_ENDPOINT.fields_by_name['kpi_sample_types'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE
+_CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM
+_TERAFLOWCONTROLLER.fields_by_name['context_id'].message_type = _CONTEXTID
+_AUTHENTICATIONRESULT.fields_by_name['context_id'].message_type = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
+DESCRIPTOR.message_types_by_name['Uuid'] = _UUID
+DESCRIPTOR.message_types_by_name['Event'] = _EVENT
+DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT
+DESCRIPTOR.message_types_by_name['ContextIdList'] = _CONTEXTIDLIST
+DESCRIPTOR.message_types_by_name['ContextList'] = _CONTEXTLIST
+DESCRIPTOR.message_types_by_name['ContextEvent'] = _CONTEXTEVENT
+DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID
+DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY
+DESCRIPTOR.message_types_by_name['TopologyIdList'] = _TOPOLOGYIDLIST
+DESCRIPTOR.message_types_by_name['TopologyList'] = _TOPOLOGYLIST
+DESCRIPTOR.message_types_by_name['TopologyEvent'] = _TOPOLOGYEVENT
+DESCRIPTOR.message_types_by_name['DeviceId'] = _DEVICEID
+DESCRIPTOR.message_types_by_name['Device'] = _DEVICE
+DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG
+DESCRIPTOR.message_types_by_name['DeviceIdList'] = _DEVICEIDLIST
+DESCRIPTOR.message_types_by_name['DeviceList'] = _DEVICELIST
+DESCRIPTOR.message_types_by_name['DeviceEvent'] = _DEVICEEVENT
+DESCRIPTOR.message_types_by_name['LinkId'] = _LINKID
+DESCRIPTOR.message_types_by_name['Link'] = _LINK
+DESCRIPTOR.message_types_by_name['LinkIdList'] = _LINKIDLIST
+DESCRIPTOR.message_types_by_name['LinkList'] = _LINKLIST
+DESCRIPTOR.message_types_by_name['LinkEvent'] = _LINKEVENT
+DESCRIPTOR.message_types_by_name['ServiceId'] = _SERVICEID
+DESCRIPTOR.message_types_by_name['Service'] = _SERVICE
+DESCRIPTOR.message_types_by_name['ServiceStatus'] = _SERVICESTATUS
+DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
+DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
+DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
+DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
+DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
+DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
+DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
+DESCRIPTOR.message_types_by_name['ConnectionList'] = _CONNECTIONLIST
+DESCRIPTOR.message_types_by_name['ConnectionEvent'] = _CONNECTIONEVENT
+DESCRIPTOR.message_types_by_name['EndPointId'] = _ENDPOINTID
+DESCRIPTOR.message_types_by_name['EndPoint'] = _ENDPOINT
+DESCRIPTOR.message_types_by_name['ConfigRule'] = _CONFIGRULE
+DESCRIPTOR.message_types_by_name['Constraint'] = _CONSTRAINT
+DESCRIPTOR.message_types_by_name['TeraFlowController'] = _TERAFLOWCONTROLLER
+DESCRIPTOR.message_types_by_name['AuthenticationResult'] = _AUTHENTICATIONRESULT
+DESCRIPTOR.enum_types_by_name['EventTypeEnum'] = _EVENTTYPEENUM
+DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
+DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
+DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
+DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
+  'DESCRIPTOR' : _EMPTY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Empty)
+  })
+_sym_db.RegisterMessage(Empty)
+
+Uuid = _reflection.GeneratedProtocolMessageType('Uuid', (_message.Message,), {
+  'DESCRIPTOR' : _UUID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Uuid)
+  })
+_sym_db.RegisterMessage(Uuid)
+
+Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), {
+  'DESCRIPTOR' : _EVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Event)
+  })
+_sym_db.RegisterMessage(Event)
+
+ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextId)
+  })
+_sym_db.RegisterMessage(ContextId)
+
+Context = _reflection.GeneratedProtocolMessageType('Context', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Context)
+  })
+_sym_db.RegisterMessage(Context)
+
+ContextIdList = _reflection.GeneratedProtocolMessageType('ContextIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextIdList)
+  })
+_sym_db.RegisterMessage(ContextIdList)
+
+ContextList = _reflection.GeneratedProtocolMessageType('ContextList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextList)
+  })
+_sym_db.RegisterMessage(ContextList)
+
+ContextEvent = _reflection.GeneratedProtocolMessageType('ContextEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextEvent)
+  })
+_sym_db.RegisterMessage(ContextEvent)
+
+TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyId)
+  })
+_sym_db.RegisterMessage(TopologyId)
+
+Topology = _reflection.GeneratedProtocolMessageType('Topology', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Topology)
+  })
+_sym_db.RegisterMessage(Topology)
+
+TopologyIdList = _reflection.GeneratedProtocolMessageType('TopologyIdList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyIdList)
+  })
+_sym_db.RegisterMessage(TopologyIdList)
+
+TopologyList = _reflection.GeneratedProtocolMessageType('TopologyList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyList)
+  })
+_sym_db.RegisterMessage(TopologyList)
+
+TopologyEvent = _reflection.GeneratedProtocolMessageType('TopologyEvent', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyEvent)
+  })
+_sym_db.RegisterMessage(TopologyEvent)
+
+DeviceId = _reflection.GeneratedProtocolMessageType('DeviceId', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceId)
+  })
+_sym_db.RegisterMessage(DeviceId)
+
+Device = _reflection.GeneratedProtocolMessageType('Device', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Device)
+  })
+_sym_db.RegisterMessage(Device)
+
+DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceConfig)
+  })
+_sym_db.RegisterMessage(DeviceConfig)
+
+DeviceIdList = _reflection.GeneratedProtocolMessageType('DeviceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceIdList)
+  })
+_sym_db.RegisterMessage(DeviceIdList)
+
+DeviceList = _reflection.GeneratedProtocolMessageType('DeviceList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceList)
+  })
+_sym_db.RegisterMessage(DeviceList)
+
+DeviceEvent = _reflection.GeneratedProtocolMessageType('DeviceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceEvent)
+  })
+_sym_db.RegisterMessage(DeviceEvent)
+
+LinkId = _reflection.GeneratedProtocolMessageType('LinkId', (_message.Message,), {
+  'DESCRIPTOR' : _LINKID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkId)
+  })
+_sym_db.RegisterMessage(LinkId)
+
+Link = _reflection.GeneratedProtocolMessageType('Link', (_message.Message,), {
+  'DESCRIPTOR' : _LINK,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Link)
+  })
+_sym_db.RegisterMessage(Link)
+
+LinkIdList = _reflection.GeneratedProtocolMessageType('LinkIdList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkIdList)
+  })
+_sym_db.RegisterMessage(LinkIdList)
+
+LinkList = _reflection.GeneratedProtocolMessageType('LinkList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkList)
+  })
+_sym_db.RegisterMessage(LinkList)
+
+LinkEvent = _reflection.GeneratedProtocolMessageType('LinkEvent', (_message.Message,), {
+  'DESCRIPTOR' : _LINKEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkEvent)
+  })
+_sym_db.RegisterMessage(LinkEvent)
+
+ServiceId = _reflection.GeneratedProtocolMessageType('ServiceId', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceId)
+  })
+_sym_db.RegisterMessage(ServiceId)
+
+Service = _reflection.GeneratedProtocolMessageType('Service', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Service)
+  })
+_sym_db.RegisterMessage(Service)
+
+ServiceStatus = _reflection.GeneratedProtocolMessageType('ServiceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceStatus)
+  })
+_sym_db.RegisterMessage(ServiceStatus)
+
+ServiceConfig = _reflection.GeneratedProtocolMessageType('ServiceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceConfig)
+  })
+_sym_db.RegisterMessage(ServiceConfig)
+
+ServiceIdList = _reflection.GeneratedProtocolMessageType('ServiceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceIdList)
+  })
+_sym_db.RegisterMessage(ServiceIdList)
+
+ServiceList = _reflection.GeneratedProtocolMessageType('ServiceList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceList)
+  })
+_sym_db.RegisterMessage(ServiceList)
+
+ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceEvent)
+  })
+_sym_db.RegisterMessage(ServiceEvent)
+
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
+ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionId)
+  })
+_sym_db.RegisterMessage(ConnectionId)
+
+Connection = _reflection.GeneratedProtocolMessageType('Connection', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTION,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Connection)
+  })
+_sym_db.RegisterMessage(Connection)
+
+ConnectionIdList = _reflection.GeneratedProtocolMessageType('ConnectionIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionIdList)
+  })
+_sym_db.RegisterMessage(ConnectionIdList)
+
+ConnectionList = _reflection.GeneratedProtocolMessageType('ConnectionList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionList)
+  })
+_sym_db.RegisterMessage(ConnectionList)
+
+ConnectionEvent = _reflection.GeneratedProtocolMessageType('ConnectionEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionEvent)
+  })
+_sym_db.RegisterMessage(ConnectionEvent)
+
+EndPointId = _reflection.GeneratedProtocolMessageType('EndPointId', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPointId)
+  })
+_sym_db.RegisterMessage(EndPointId)
+
+EndPoint = _reflection.GeneratedProtocolMessageType('EndPoint', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPoint)
+  })
+_sym_db.RegisterMessage(EndPoint)
+
+ConfigRule = _reflection.GeneratedProtocolMessageType('ConfigRule', (_message.Message,), {
+  'DESCRIPTOR' : _CONFIGRULE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConfigRule)
+  })
+_sym_db.RegisterMessage(ConfigRule)
+
+Constraint = _reflection.GeneratedProtocolMessageType('Constraint', (_message.Message,), {
+  'DESCRIPTOR' : _CONSTRAINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Constraint)
+  })
+_sym_db.RegisterMessage(Constraint)
+
+TeraFlowController = _reflection.GeneratedProtocolMessageType('TeraFlowController', (_message.Message,), {
+  'DESCRIPTOR' : _TERAFLOWCONTROLLER,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TeraFlowController)
+  })
+_sym_db.RegisterMessage(TeraFlowController)
+
+AuthenticationResult = _reflection.GeneratedProtocolMessageType('AuthenticationResult', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHENTICATIONRESULT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.AuthenticationResult)
+  })
+_sym_db.RegisterMessage(AuthenticationResult)
+
+
+
+_CONTEXTSERVICE = _descriptor.ServiceDescriptor(
+  name='ContextService',
+  full_name='context.ContextService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=5273,
+  serialized_end=7688,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='ListContextIds',
+    full_name='context.ContextService.ListContextIds',
+    index=0,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListContexts',
+    full_name='context.ContextService.ListContexts',
+    index=1,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContext',
+    full_name='context.ContextService.GetContext',
+    index=2,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_CONTEXT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetContext',
+    full_name='context.ContextService.SetContext',
+    index=3,
+    containing_service=None,
+    input_type=_CONTEXT,
+    output_type=_CONTEXTID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveContext',
+    full_name='context.ContextService.RemoveContext',
+    index=4,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContextEvents',
+    full_name='context.ContextService.GetContextEvents',
+    index=5,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologyIds',
+    full_name='context.ContextService.ListTopologyIds',
+    index=6,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologies',
+    full_name='context.ContextService.ListTopologies',
+    index=7,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopology',
+    full_name='context.ContextService.GetTopology',
+    index=8,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_TOPOLOGY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetTopology',
+    full_name='context.ContextService.SetTopology',
+    index=9,
+    containing_service=None,
+    input_type=_TOPOLOGY,
+    output_type=_TOPOLOGYID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveTopology',
+    full_name='context.ContextService.RemoveTopology',
+    index=10,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopologyEvents',
+    full_name='context.ContextService.GetTopologyEvents',
+    index=11,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_TOPOLOGYEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDeviceIds',
+    full_name='context.ContextService.ListDeviceIds',
+    index=12,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDevices',
+    full_name='context.ContextService.ListDevices',
+    index=13,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDevice',
+    full_name='context.ContextService.GetDevice',
+    index=14,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_DEVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetDevice',
+    full_name='context.ContextService.SetDevice',
+    index=15,
+    containing_service=None,
+    input_type=_DEVICE,
+    output_type=_DEVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveDevice',
+    full_name='context.ContextService.RemoveDevice',
+    index=16,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDeviceEvents',
+    full_name='context.ContextService.GetDeviceEvents',
+    index=17,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinkIds',
+    full_name='context.ContextService.ListLinkIds',
+    index=18,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinks',
+    full_name='context.ContextService.ListLinks',
+    index=19,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLink',
+    full_name='context.ContextService.GetLink',
+    index=20,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_LINK,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetLink',
+    full_name='context.ContextService.SetLink',
+    index=21,
+    containing_service=None,
+    input_type=_LINK,
+    output_type=_LINKID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveLink',
+    full_name='context.ContextService.RemoveLink',
+    index=22,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLinkEvents',
+    full_name='context.ContextService.GetLinkEvents',
+    index=23,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServiceIds',
+    full_name='context.ContextService.ListServiceIds',
+    index=24,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServices',
+    full_name='context.ContextService.ListServices',
+    index=25,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetService',
+    full_name='context.ContextService.GetService',
+    index=26,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_SERVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetService',
+    full_name='context.ContextService.SetService',
+    index=27,
+    containing_service=None,
+    input_type=_SERVICE,
+    output_type=_SERVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveService',
+    full_name='context.ContextService.RemoveService',
+    index=28,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetServiceEvents',
+    full_name='context.ContextService.GetServiceEvents',
+    index=29,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SERVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnectionIds',
+    full_name='context.ContextService.ListConnectionIds',
+    index=36,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnections',
+    full_name='context.ContextService.ListConnections',
+    index=37,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnection',
+    full_name='context.ContextService.GetConnection',
+    index=38,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_CONNECTION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetConnection',
+    full_name='context.ContextService.SetConnection',
+    index=39,
+    containing_service=None,
+    input_type=_CONNECTION,
+    output_type=_CONNECTIONID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveConnection',
+    full_name='context.ContextService.RemoveConnection',
+    index=40,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnectionEvents',
+    full_name='context.ContextService.GetConnectionEvents',
+    index=41,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONNECTIONEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CONTEXTSERVICE)
+
+DESCRIPTOR.services_by_name['ContextService'] = _CONTEXTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/interdomain/proto/interdomain_pb2.py b/src/interdomain/proto/interdomain_pb2.py
new file mode 100644
index 000000000..3f2dff89f
--- /dev/null
+++ b/src/interdomain/proto/interdomain_pb2.py
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: interdomain.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import context_pb2 as context__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='interdomain.proto',
+  package='interdomain',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x11interdomain.proto\x12\x0binterdomain\x1a\rcontext.proto2\xc4\x02\n\x12InterdomainService\x12\x32\n\x0cRequestSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12L\n\x0c\x41uthenticate\x12\x1b.context.TeraFlowController\x1a\x1d.context.AuthenticationResult\"\x00\x12\x31\n\x0bLookUpSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x39\n\x15OrderSliceFromCatalog\x12\x0e.context.Slice\x1a\x0e.context.Slice\"\x00\x12>\n\x1a\x43reateSliceAndAddToCatalog\x12\x0e.context.Slice\x1a\x0e.context.Slice\"\x00\x62\x06proto3'
+  ,
+  dependencies=[context__pb2.DESCRIPTOR,])
+
+
+
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+_INTERDOMAINSERVICE = _descriptor.ServiceDescriptor(
+  name='InterdomainService',
+  full_name='interdomain.InterdomainService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=50,
+  serialized_end=374,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='RequestSlice',
+    full_name='interdomain.InterdomainService.RequestSlice',
+    index=0,
+    containing_service=None,
+    input_type=context__pb2._SLICE,
+    output_type=context__pb2._SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='Authenticate',
+    full_name='interdomain.InterdomainService.Authenticate',
+    index=1,
+    containing_service=None,
+    input_type=context__pb2._TERAFLOWCONTROLLER,
+    output_type=context__pb2._AUTHENTICATIONRESULT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='LookUpSlice',
+    full_name='interdomain.InterdomainService.LookUpSlice',
+    index=2,
+    containing_service=None,
+    input_type=context__pb2._SLICE,
+    output_type=context__pb2._SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='OrderSliceFromCatalog',
+    full_name='interdomain.InterdomainService.OrderSliceFromCatalog',
+    index=3,
+    containing_service=None,
+    input_type=context__pb2._SLICE,
+    output_type=context__pb2._SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='CreateSliceAndAddToCatalog',
+    full_name='interdomain.InterdomainService.CreateSliceAndAddToCatalog',
+    index=4,
+    containing_service=None,
+    input_type=context__pb2._SLICE,
+    output_type=context__pb2._SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_INTERDOMAINSERVICE)
+
+DESCRIPTOR.services_by_name['InterdomainService'] = _INTERDOMAINSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/interdomain/proto/interdomain_pb2_grpc.py b/src/interdomain/proto/interdomain_pb2_grpc.py
new file mode 100644
index 000000000..0973228d0
--- /dev/null
+++ b/src/interdomain/proto/interdomain_pb2_grpc.py
@@ -0,0 +1,198 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+from . import context_pb2 as context__pb2
+
+
+class InterdomainServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.RequestSlice = channel.unary_unary(
+                '/interdomain.InterdomainService/RequestSlice',
+                request_serializer=context__pb2.Slice.SerializeToString,
+                response_deserializer=context__pb2.SliceId.FromString,
+                )
+        self.Authenticate = channel.unary_unary(
+                '/interdomain.InterdomainService/Authenticate',
+                request_serializer=context__pb2.TeraFlowController.SerializeToString,
+                response_deserializer=context__pb2.AuthenticationResult.FromString,
+                )
+        self.LookUpSlice = channel.unary_unary(
+                '/interdomain.InterdomainService/LookUpSlice',
+                request_serializer=context__pb2.Slice.SerializeToString,
+                response_deserializer=context__pb2.SliceId.FromString,
+                )
+        self.OrderSliceFromCatalog = channel.unary_unary(
+                '/interdomain.InterdomainService/OrderSliceFromCatalog',
+                request_serializer=context__pb2.Slice.SerializeToString,
+                response_deserializer=context__pb2.Slice.FromString,
+                )
+        self.CreateSliceAndAddToCatalog = channel.unary_unary(
+                '/interdomain.InterdomainService/CreateSliceAndAddToCatalog',
+                request_serializer=context__pb2.Slice.SerializeToString,
+                response_deserializer=context__pb2.Slice.FromString,
+                )
+
+
+class InterdomainServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def RequestSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def Authenticate(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def LookUpSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def OrderSliceFromCatalog(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def CreateSliceAndAddToCatalog(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_InterdomainServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'RequestSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.RequestSlice,
+                    request_deserializer=context__pb2.Slice.FromString,
+                    response_serializer=context__pb2.SliceId.SerializeToString,
+            ),
+            'Authenticate': grpc.unary_unary_rpc_method_handler(
+                    servicer.Authenticate,
+                    request_deserializer=context__pb2.TeraFlowController.FromString,
+                    response_serializer=context__pb2.AuthenticationResult.SerializeToString,
+            ),
+            'LookUpSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.LookUpSlice,
+                    request_deserializer=context__pb2.Slice.FromString,
+                    response_serializer=context__pb2.SliceId.SerializeToString,
+            ),
+            'OrderSliceFromCatalog': grpc.unary_unary_rpc_method_handler(
+                    servicer.OrderSliceFromCatalog,
+                    request_deserializer=context__pb2.Slice.FromString,
+                    response_serializer=context__pb2.Slice.SerializeToString,
+            ),
+            'CreateSliceAndAddToCatalog': grpc.unary_unary_rpc_method_handler(
+                    servicer.CreateSliceAndAddToCatalog,
+                    request_deserializer=context__pb2.Slice.FromString,
+                    response_serializer=context__pb2.Slice.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'interdomain.InterdomainService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class InterdomainService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def RequestSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/interdomain.InterdomainService/RequestSlice',
+            context__pb2.Slice.SerializeToString,
+            context__pb2.SliceId.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def Authenticate(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/interdomain.InterdomainService/Authenticate',
+            context__pb2.TeraFlowController.SerializeToString,
+            context__pb2.AuthenticationResult.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def LookUpSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/interdomain.InterdomainService/LookUpSlice',
+            context__pb2.Slice.SerializeToString,
+            context__pb2.SliceId.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def OrderSliceFromCatalog(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/interdomain.InterdomainService/OrderSliceFromCatalog',
+            context__pb2.Slice.SerializeToString,
+            context__pb2.Slice.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def CreateSliceAndAddToCatalog(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/interdomain.InterdomainService/CreateSliceAndAddToCatalog',
+            context__pb2.Slice.SerializeToString,
+            context__pb2.Slice.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/interdomain/proto/kpi_sample_types_pb2.py b/src/interdomain/proto/kpi_sample_types_pb2.py
new file mode 100644
index 000000000..ea7fd2f82
--- /dev/null
+++ b/src/interdomain/proto/kpi_sample_types_pb2.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: kpi_sample_types.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='kpi_sample_types.proto',
+  package='kpi_sample_types',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*\xbe\x01\n\rKpiSampleType\x12\x19\n\x15KPISAMPLETYPE_UNKNOWN\x10\x00\x12%\n!KPISAMPLETYPE_PACKETS_TRANSMITTED\x10\x65\x12\"\n\x1eKPISAMPLETYPE_PACKETS_RECEIVED\x10\x66\x12$\n\x1fKPISAMPLETYPE_BYTES_TRANSMITTED\x10\xc9\x01\x12!\n\x1cKPISAMPLETYPE_BYTES_RECEIVED\x10\xca\x01\x62\x06proto3'
+)
+
+_KPISAMPLETYPE = _descriptor.EnumDescriptor(
+  name='KpiSampleType',
+  full_name='kpi_sample_types.KpiSampleType',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_TRANSMITTED', index=1, number=101,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_RECEIVED', index=2, number=102,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_TRANSMITTED', index=3, number=201,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_RECEIVED', index=4, number=202,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=45,
+  serialized_end=235,
+)
+_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE)
+
+KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE)
+KPISAMPLETYPE_UNKNOWN = 0
+KPISAMPLETYPE_PACKETS_TRANSMITTED = 101
+KPISAMPLETYPE_PACKETS_RECEIVED = 102
+KPISAMPLETYPE_BYTES_TRANSMITTED = 201
+KPISAMPLETYPE_BYTES_RECEIVED = 202
+
+
+DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/interdomain/proto/slice_pb2.py b/src/interdomain/proto/slice_pb2.py
new file mode 100644
index 000000000..1e2a5f31c
--- /dev/null
+++ b/src/interdomain/proto/slice_pb2.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: slice.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import context_pb2 as context__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='slice.proto',
+  package='slice',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x0bslice.proto\x12\x05slice\x1a\rcontext.proto2\xa7\x01\n\x0cSliceService\x12\x31\n\x0b\x43reateSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bUpdateSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0b\x44\x65leteSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
+  ,
+  dependencies=[context__pb2.DESCRIPTOR,])
+
+
+
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+_SLICESERVICE = _descriptor.ServiceDescriptor(
+  name='SliceService',
+  full_name='slice.SliceService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=38,
+  serialized_end=205,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='CreateSlice',
+    full_name='slice.SliceService.CreateSlice',
+    index=0,
+    containing_service=None,
+    input_type=context__pb2._SLICE,
+    output_type=context__pb2._SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='UpdateSlice',
+    full_name='slice.SliceService.UpdateSlice',
+    index=1,
+    containing_service=None,
+    input_type=context__pb2._SLICE,
+    output_type=context__pb2._SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='DeleteSlice',
+    full_name='slice.SliceService.DeleteSlice',
+    index=2,
+    containing_service=None,
+    input_type=context__pb2._SLICEID,
+    output_type=context__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_SLICESERVICE)
+
+DESCRIPTOR.services_by_name['SliceService'] = _SLICESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/interdomain/requirements.in b/src/interdomain/requirements.in
new file mode 100644
index 000000000..162ecde82
--- /dev/null
+++ b/src/interdomain/requirements.in
@@ -0,0 +1,6 @@
+grpcio==1.43.0
+grpcio-health-checking==1.43.0
+prometheus-client==0.13.0
+protobuf==3.19.3
+pytest==6.2.5
+pytest-benchmark==3.4.1
diff --git a/src/interdomain/service/InterdomainService.py b/src/interdomain/service/InterdomainService.py
new file mode 100644
index 000000000..debc943cf
--- /dev/null
+++ b/src/interdomain/service/InterdomainService.py
@@ -0,0 +1,76 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from concurrent import futures
+from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
+from grpc_health.v1.health_pb2 import HealthCheckResponse
+from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
+from context.client.ContextClient import ContextClient
+from interdomain.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+from interdomain.proto.interdomain_pb2_grpc import add_InterdomainServiceServicer_to_server
+from slice.client.SliceClient import SliceClient
+from .InterdomainServiceServicerImpl import InterdomainServiceServicerImpl
+from .RemoteDomainClients import RemoteDomainClients
+
+BIND_ADDRESS = '0.0.0.0'
+LOGGER = logging.getLogger(__name__)
+
+class InterdomainService:
+    def __init__(
+        self, context_client : ContextClient, slice_client : SliceClient, remote_domain_clients : RemoteDomainClients,
+        address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD
+    ):
+        self.context_client = context_client
+        self.slice_client = slice_client
+        self.remote_domain_clients = remote_domain_clients
+        self.address = address
+        self.port = port
+        self.endpoint = None
+        self.max_workers = max_workers
+        self.grace_period = grace_period
+        self.interdomain_servicer = None
+        self.health_servicer = None
+        self.pool = None
+        self.server = None
+
+    def start(self):
+        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
+        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
+            str(self.endpoint), str(self.max_workers)))
+
+        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
+        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
+
+        self.interdomain_servicer = InterdomainServiceServicerImpl(
+            self.context_client, self.slice_client, self.remote_domain_clients)
+        add_InterdomainServiceServicer_to_server(self.interdomain_servicer, self.server)
+
+        self.health_servicer = HealthServicer(
+            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
+        add_HealthServicer_to_server(self.health_servicer, self.server)
+
+        port = self.server.add_insecure_port(self.endpoint)
+        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
+        LOGGER.info('Listening on {:s}...'.format(str(self.endpoint)))
+        self.server.start()
+        self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
+
+        LOGGER.debug('Service started')
+
+    def stop(self):
+        LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
+        self.health_servicer.enter_graceful_shutdown()
+        self.server.stop(self.grace_period)
+        LOGGER.debug('Service stopped')
diff --git a/src/interdomain/service/InterdomainServiceServicerImpl.py b/src/interdomain/service/InterdomainServiceServicerImpl.py
new file mode 100644
index 000000000..e76297625
--- /dev/null
+++ b/src/interdomain/service/InterdomainServiceServicerImpl.py
@@ -0,0 +1,152 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import SliceStatusEnum
+from interdomain.proto.context_pb2 import AuthenticationResult, Slice, SliceId, SliceStatus, TeraFlowController
+from interdomain.proto.interdomain_pb2_grpc import InterdomainServiceServicer
+from interdomain.service.RemoteDomainClients import RemoteDomainClients
+from slice.client.SliceClient import SliceClient
+
+LOGGER = logging.getLogger(__name__)
+
+SERVICE_NAME = 'Interdomain'
+METHOD_NAMES = ['RequestSlice', 'Authenticate', 'LookUpSlice', 'OrderSliceFromCatalog', 'CreateSliceAndAddToCatalog']
+METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
+
+class InterdomainServiceServicerImpl(InterdomainServiceServicer):
+    def __init__(
+        self, context_client : ContextClient, slice_client : SliceClient,
+        remote_domain_clients : RemoteDomainClients
+    ):
+        LOGGER.debug('Creating Servicer...')
+        self.context_client = context_client
+        self.slice_client = slice_client
+        self.remote_domain_clients = remote_domain_clients
+        LOGGER.debug('Servicer Created')
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def RequestSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
+        domains_to_endpoints = {}
+        local_domain_uuid = None
+        for slice_endpoint_id in request.slice_endpoint_ids:
+            device_uuid = slice_endpoint_id.device_id.device_uuid.uuid
+            domain_uuid = device_uuid.split('@')[1]
+            endpoints = domains_to_endpoints.setdefault(domain_uuid, [])
+            endpoints.append(slice_endpoint_id)
+            if local_domain_uuid is None: local_domain_uuid = domain_uuid
+
+        reply = Slice()
+        reply.CopyFrom(request)
+
+        # decompose remote slices
+        for domain_uuid, slice_endpoint_ids in domains_to_endpoints.items():
+            if domain_uuid == local_domain_uuid: continue
+
+            remote_slice_request = Slice()
+            remote_slice_request.slice_id.context_id.context_uuid.uuid = request.slice_id.context_id.context_uuid.uuid
+            remote_slice_request.slice_id.slice_uuid.uuid = \
+                request.slice_id.slice_uuid.uuid + ':subslice@' + local_domain_uuid
+            remote_slice_request.slice_status.slice_status = request.slice_status.slice_status
+            for endpoint_id in slice_endpoint_ids:
+                slice_endpoint_id = remote_slice_request.slice_endpoint_ids.add()
+                slice_endpoint_id.device_id.device_uuid.uuid = endpoint_id.device_id.device_uuid.uuid
+                slice_endpoint_id.endpoint_uuid.uuid = endpoint_id.endpoint_uuid.uuid
+
+            # add endpoint connecting to remote domain
+            if domain_uuid == 'D1':
+                slice_endpoint_id = remote_slice_request.slice_endpoint_ids.add()
+                slice_endpoint_id.device_id.device_uuid.uuid = 'R4@D1'
+                slice_endpoint_id.endpoint_uuid.uuid = '2/1'
+            elif domain_uuid == 'D2':
+                slice_endpoint_id = remote_slice_request.slice_endpoint_ids.add()
+                slice_endpoint_id.device_id.device_uuid.uuid = 'R1@D2'
+                slice_endpoint_id.endpoint_uuid.uuid = '2/1'
+
+            interdomain_client = self.remote_domain_clients.get_peer('remote-teraflow')
+            remote_slice_reply = interdomain_client.LookUpSlice(remote_slice_request)
+            if remote_slice_reply == remote_slice_request.slice_id: # pylint: disable=no-member
+                # successful case
+                remote_slice = interdomain_client.OrderSliceFromCatalog(remote_slice_request)
+                if remote_slice.slice_status.slice_status != SliceStatusEnum.SLICESTATUS_ACTIVE:
+                    raise Exception('Remote Slice creation failed. Wrong Slice status returned')
+            else:
+                # not in catalog
+                remote_slice = interdomain_client.CreateSliceAndAddToCatalog(remote_slice_request)
+                if remote_slice.slice_status.slice_status != SliceStatusEnum.SLICESTATUS_ACTIVE:
+                    raise Exception('Remote Slice creation failed. Wrong Slice status returned')
+
+            #self.context_client.SetSlice(remote_slice)
+            #subslice_id = reply.slice_subslice_ids.add()
+            #subslice_id.CopyFrom(remote_slice.slice_id)
+
+        local_slice_request = Slice()
+        local_slice_request.slice_id.context_id.context_uuid.uuid = request.slice_id.context_id.context_uuid.uuid
+        local_slice_request.slice_id.slice_uuid.uuid = request.slice_id.slice_uuid.uuid + ':subslice'
+        local_slice_request.slice_status.slice_status = request.slice_status.slice_status
+        for endpoint_id in domains_to_endpoints[local_domain_uuid]:
+            slice_endpoint_id = local_slice_request.slice_endpoint_ids.add()
+            slice_endpoint_id.CopyFrom(endpoint_id)
+
+        # add endpoint connecting to remote domain
+        if local_domain_uuid == 'D1':
+            slice_endpoint_id = local_slice_request.slice_endpoint_ids.add()
+            slice_endpoint_id.device_id.device_uuid.uuid = 'R4@D1'
+            slice_endpoint_id.endpoint_uuid.uuid = '2/1'
+        elif local_domain_uuid == 'D2':
+            slice_endpoint_id = local_slice_request.slice_endpoint_ids.add()
+            slice_endpoint_id.device_id.device_uuid.uuid = 'R1@D2'
+            slice_endpoint_id.endpoint_uuid.uuid = '2/1'
+
+        local_slice_reply = self.slice_client.CreateSlice(local_slice_request)
+        if local_slice_reply != local_slice_request.slice_id: # pylint: disable=no-member
+            raise Exception('Local Slice creation failed. Wrong Slice Id was returned')
+
+        subslice_id = reply.slice_subslice_ids.add()
+        subslice_id.context_id.context_uuid.uuid = local_slice_request.slice_id.context_id.context_uuid.uuid
+        subslice_id.slice_uuid.uuid = local_slice_request.slice_id.slice_uuid.uuid
+
+        self.context_client.SetSlice(reply)
+        return reply.slice_id
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def Authenticate(self, request : TeraFlowController, context : grpc.ServicerContext) -> AuthenticationResult:
+        auth_result = AuthenticationResult()
+        auth_result.context_id.CopyFrom(request.context_id) # pylint: disable=no-member
+        auth_result.authenticated = True
+        return auth_result
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def LookUpSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
+        try:
+            slice_ = self.context_client.GetSlice(request.slice_id)
+            return slice_.slice_id
+        except grpc.RpcError:
+            #LOGGER.exception('Unable to get slice({:s})'.format(grpc_message_to_json_string(request.slice_id)))
+            return SliceId()
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def OrderSliceFromCatalog(self, request : Slice, context : grpc.ServicerContext) -> Slice:
+        raise NotImplementedError('OrderSliceFromCatalog')
+        #return Slice()
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def CreateSliceAndAddToCatalog(self, request : Slice, context : grpc.ServicerContext) -> Slice:
+        reply = self.slice_client.CreateSlice(request)
+        if reply != request.slice_id: # pylint: disable=no-member
+            raise Exception('Slice creation failed. Wrong Slice Id was returned')
+        return self.context_client.GetSlice(request.slice_id)
diff --git a/src/interdomain/service/RemoteDomainClients.py b/src/interdomain/service/RemoteDomainClients.py
new file mode 100644
index 000000000..709aa3c07
--- /dev/null
+++ b/src/interdomain/service/RemoteDomainClients.py
@@ -0,0 +1,56 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, socket
+from common.Constants import DEFAULT_CONTEXT_UUID
+from common.Settings import get_setting
+from interdomain.Config import GRPC_SERVICE_PORT
+from interdomain.client.InterdomainClient import InterdomainClient
+from interdomain.proto.context_pb2 import TeraFlowController
+
+LOGGER = logging.getLogger(__name__)
+
+class RemoteDomainClients:
+    def __init__(self) -> None:
+        self.peer_domain = {}
+
+    def add_peer(
+            self, domain_name : str, address : str, port : int, context_uuid : str = DEFAULT_CONTEXT_UUID
+        ) -> None:
+        while True:
+            try:
+                remote_teraflow_ip = socket.gethostbyname(address)
+                if len(remote_teraflow_ip) > 0: break
+            except socket.gaierror as e:
+                if str(e) == '[Errno -2] Name or service not known': continue
+
+        interdomain_client = InterdomainClient(address, port)
+        request = TeraFlowController()
+        request.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID # pylint: disable=no-member
+        request.ip_address = get_setting('INTERDOMAINSERVICE_SERVICE_HOST', default='0.0.0.0')
+        request.port = int(get_setting('INTERDOMAINSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT))
+
+        reply = interdomain_client.Authenticate(request)
+        if not reply.authenticated:
+            msg = 'Authentication against {:s}:{:d} rejected'
+            raise Exception(msg.format(str(remote_teraflow_ip), GRPC_SERVICE_PORT))
+
+        self.peer_domain[domain_name] = interdomain_client
+
+    def get_peer(self, domain_name : str) -> InterdomainClient:
+        LOGGER.warning('peers: {:s}'.format(str(self.peer_domain)))
+        return self.peer_domain.get(domain_name)
+
+    def remove_peer(self, domain_name : str) -> None:
+        return self.peer_domain.pop(domain_name, None)
diff --git a/src/interdomain/service/__init__.py b/src/interdomain/service/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/interdomain/service/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/interdomain/service/__main__.py b/src/interdomain/service/__main__.py
new file mode 100644
index 000000000..ff19271ee
--- /dev/null
+++ b/src/interdomain/service/__main__.py
@@ -0,0 +1,96 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, signal, sys, threading
+from prometheus_client import start_http_server
+from common.Settings import get_setting, wait_for_environment_variables
+from context.client.ContextClient import ContextClient
+from interdomain.service.RemoteDomainClients import RemoteDomainClients
+from interdomain.Config import (
+    CONTEXT_SERVICE_HOST, CONTEXT_SERVICE_PORT, SLICE_SERVICE_HOST, SLICE_SERVICE_PORT, GRPC_SERVICE_PORT,
+    GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT)
+from slice.client.SliceClient import SliceClient
+from .InterdomainService import InterdomainService
+
+terminate = threading.Event()
+LOGGER : logging.Logger = None
+
+def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
+    LOGGER.warning('Terminate signal received')
+    terminate.set()
+
+def main():
+    global LOGGER # pylint: disable=global-statement
+
+    grpc_service_port       = get_setting('INTERDOMAINSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT      )
+    max_workers             = get_setting('MAX_WORKERS',                          default=GRPC_MAX_WORKERS       )
+    grace_period            = get_setting('GRACE_PERIOD',                         default=GRPC_GRACE_PERIOD      )
+    log_level               = get_setting('LOG_LEVEL',                            default=LOG_LEVEL              )
+    metrics_port            = get_setting('METRICS_PORT',                         default=METRICS_PORT           )
+
+    logging.basicConfig(level=log_level)
+    LOGGER = logging.getLogger(__name__)
+
+    wait_for_environment_variables([
+        'CONTEXTSERVICE_SERVICE_HOST', 'CONTEXTSERVICE_SERVICE_PORT_GRPC',
+        'SLICESERVICE_SERVICE_HOST', 'SLICESERVICE_SERVICE_PORT_GRPC',
+    ])
+
+    context_service_host    = get_setting('CONTEXTSERVICE_SERVICE_HOST',          default=CONTEXT_SERVICE_HOST   )
+    context_service_port    = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC',     default=CONTEXT_SERVICE_PORT   )
+    slice_service_host      = get_setting('SLICESERVICE_SERVICE_HOST',            default=SLICE_SERVICE_HOST     )
+    slice_service_port      = get_setting('SLICESERVICE_SERVICE_PORT_GRPC',       default=SLICE_SERVICE_PORT     )
+
+    signal.signal(signal.SIGINT,  signal_handler)
+    signal.signal(signal.SIGTERM, signal_handler)
+
+    LOGGER.info('Starting...')
+
+    # Start metrics server
+    start_http_server(metrics_port)
+
+    # Initialize Context Client
+    if context_service_host is None or context_service_port is None:
+        raise Exception('Wrong address({:s}):port({:s}) of Context component'.format(
+            str(context_service_host), str(context_service_port)))
+    context_client = ContextClient(context_service_host, context_service_port)
+
+    # Initialize Slice Client
+    if slice_service_host is None or slice_service_port is None:
+        raise Exception('Wrong address({:s}):port({:s}) of Slice component'.format(
+            str(slice_service_host), str(slice_service_port)))
+    slice_client = SliceClient(slice_service_host, slice_service_port)
+
+    # Define remote domain clients
+    remote_domain_clients = RemoteDomainClients()
+
+    # Starting Interdomain service
+    grpc_service = InterdomainService(
+        context_client, slice_client, remote_domain_clients, port=grpc_service_port, max_workers=max_workers,
+        grace_period=grace_period)
+    grpc_service.start()
+
+    remote_domain_clients.add_peer('remote-teraflow', 'remote-teraflow', GRPC_SERVICE_PORT)
+
+    # Wait for Ctrl+C or termination signal
+    while not terminate.wait(timeout=0.1): pass
+
+    LOGGER.info('Terminating...')
+    grpc_service.stop()
+
+    LOGGER.info('Bye')
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/src/interdomain/tests/__init__.py b/src/interdomain/tests/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/interdomain/tests/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/interdomain/tests/test_unitary.py b/src/interdomain/tests/test_unitary.py
new file mode 100644
index 000000000..bcc6bb9c9
--- /dev/null
+++ b/src/interdomain/tests/test_unitary.py
@@ -0,0 +1,146 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import logging, grpc
+import os
+import sqlite3
+
+import pytest
+from typing import Tuple
+
+from interdomain.proto import context_pb2, kpi_sample_types_pb2, monitoring_pb2
+from interdomain.client.interdomain_client import InterdomainClient
+from interdomain.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+from interdomain.service.InterdomainService import InterdomainService
+
+from common.orm.Database import Database
+from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
+from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
+from common.message_broker.MessageBroker import MessageBroker
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+###########################
+# Tests Setup
+###########################
+
+SERVER_ADDRESS = '127.0.0.1'
+LISTEN_ADDRESS = '[::]'
+GRPC_PORT_MONITORING = 9090
+
+GRPC_PORT_CONTEXT    = 10000 + grpc_port_context    # avoid privileged ports
+
+SCENARIOS = [ # comment/uncomment scenarios to activate/deactivate them in the test unit
+    ('all_inmemory', DatabaseBackendEnum.INMEMORY, {},           MessageBrokerBackendEnum.INMEMORY, {}          ),
+]
+
+
+# This fixture will be requested by test cases and last during testing session
+@pytest.fixture(scope='session')
+def interdomain_service():
+    LOGGER.warning('interdomain_service begin')
+
+    interdomain_port    = GRPC_INTERDOMAIN_PORT
+    max_workers     = GRPC_MAX_WORKERS
+    grace_period    = GRPC_GRACE_PERIOD
+
+    LOGGER.info('Initializing InterdomainService...')
+    grpc_service = InterdomainService(port=interdomain_port, max_workers=max_workers, grace_period=grace_period)
+    server = grpc_service.start()
+
+    # yield the server, when test finishes, execution will resume to stop it
+    LOGGER.warning('interdomain_service yielding')
+    yield server
+
+    LOGGER.info('Terminating InterdomainService...')
+    grpc_service.stop()
+
+# This fixture will be requested by test cases and last during testing session.
+# The client requires the server, so client fixture has the server as dependency.
+@pytest.fixture(scope='session')
+def interdomain_client(interdomain_service):
+    LOGGER.warning('interdomain_client begin')
+    client = InterdomainClient(server=SERVER_ADDRESS, port=GRPC_PORT_INTERDOMAIN)  # instantiate the client
+    LOGGER.warning('interdomain_client returning')
+    return client
+
+# This fixture will be requested by test cases and last during testing session.
+@pytest.fixture(scope='session')
+def create_TeraFlowController():
+    LOGGER.warning('create_TeraFlowController begin')
+    # form request
+    tf_ctl                  = context_pb2.TeraFlowController()
+    tf_ctl.context_id       = context_pb2.ContextId()
+    tf_ctl.context_id.context_uuid = context_pb2.Uuid()
+    tf_ctl.context_id.context_uuid.uuid = str(1) 
+    tf_ctl.ip_address       = "127.0.0.1"
+    tf_ctl.port      	    = 9090
+    return tf_ctl
+
+@pytest.fixture(scope='session')
+def create_TransportSlice():
+    LOGGER.warning('create_TransportSlice begin')
+
+    # form request
+    slice_req              = slice_pb2.TransportSlice()
+    slice_req.contextId    = context_pb2.ContextId()
+    slice_req.contextId.context_uuid = context_pb2.Uuid()
+    slice_req.contextId.context_uuid.uuid = str(1) 
+    slice_req.slice_id     = context_pb2.Uuid()
+    slice_req.slice_id.context_uuid.uuid = str(1) 
+
+    return slice_req
+
+
+###########################
+# Tests Implementation
+###########################
+
+
+# Test case that makes use of client fixture to test server's CreateKpi method
+def test_Authenticate(interdomain_client,create_TeraFlowController):
+    # make call to server
+    LOGGER.warning('test_Authenticate requesting')
+    response = interdomain_client.Authenticate(create_TeraFlowController)
+    LOGGER.debug(str(response))
+    assert isinstance(response, context.AuthenticationResult)
+
+# Test case that makes use of client fixture to test server's MonitorKpi method
+def test_LookUpSlice(interdomain_client,create_TransportSlice):
+    LOGGER.warning('test_LookUpSlice begin')
+
+    response = interdomain_client.LookUpSlice(create_TransportSlice)
+    LOGGER.debug(str(response))
+    assert isinstance(response, slice.SliceId)
+
+# Test case that makes use of client fixture to test server's GetStreamKpi method
+def test_CreateSliceAndAddToCatalog(interdomain_client,create_TransportSlice):
+    LOGGER.warning('test_CreateSliceAndAddToCatalog begin')
+    response = interdomain_client.CreateSliceAndAddToCatalog(create_TransportSlice)
+    LOGGER.debug(str(response))
+    assert isinstance(response, slice.SliceId)
+
+# Test case that makes use of client fixture to test server's IncludeKpi method
+def test_OrderSliceFromCatalog(interdomain_client,create_TransportSlice):
+    # make call to server
+    LOGGER.warning('test_OrderSliceFromCatalog requesting')
+    response = interdomain_client.OrderSliceFromCatalog(create_TransportSlice)
+    LOGGER.debug(str(response))
+    assert isinstance(response, slice.SliceId)
+
+
+
+
diff --git a/src/l3_attackmitigator/genproto.sh b/src/l3_attackmitigator/genproto.sh
old mode 100644
new mode 100755
index 40635e44a..c69f7d025
--- a/src/l3_attackmitigator/genproto.sh
+++ b/src/l3_attackmitigator/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,16 +14,36 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto l3_attackmitigator.proto
 
+rm proto/context_pb2_grpc.py
+rm proto/kpi_sample_types_pb2_grpc.py
+
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py
 sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/l3_attackmitigator_pb2.py
 sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/l3_attackmitigator_pb2_grpc.py
diff --git a/src/l3_attackmitigator/proto/context_pb2.py b/src/l3_attackmitigator/proto/context_pb2.py
new file mode 100644
index 000000000..50d501d3a
--- /dev/null
+++ b/src/l3_attackmitigator/proto/context_pb2.py
@@ -0,0 +1,3071 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: context.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import kpi_sample_types_pb2 as kpi__sample__types__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='context.proto',
+  package='context',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  ,
+  dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
+
+_EVENTTYPEENUM = _descriptor.EnumDescriptor(
+  name='EventTypeEnum',
+  full_name='context.EventTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_CREATE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UPDATE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_REMOVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4310,
+  serialized_end=4416,
+)
+_sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
+
+EventTypeEnum = enum_type_wrapper.EnumTypeWrapper(_EVENTTYPEENUM)
+_DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
+  name='DeviceDriverEnum',
+  full_name='context.DeviceDriverEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_OPENCONFIG', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_TRANSPORT_API', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_P4', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_IETF_NETWORK_TOPOLOGY', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_ONF_TR_352', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4419,
+  serialized_end=4616,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
+
+DeviceDriverEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEDRIVERENUM)
+_DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
+  name='DeviceOperationalStatusEnum',
+  full_name='context.DeviceOperationalStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_DISABLED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_ENABLED', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4619,
+  serialized_end=4762,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
+
+DeviceOperationalStatusEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEOPERATIONALSTATUSENUM)
+_SERVICETYPEENUM = _descriptor.EnumDescriptor(
+  name='ServiceTypeEnum',
+  full_name='context.ServiceTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L3NM', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L2NM', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_TAPI_CONNECTIVITY_SERVICE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4765,
+  serialized_end=4894,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
+
+ServiceTypeEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPEENUM)
+_SERVICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='ServiceStatusEnum',
+  full_name='context.ServiceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_ACTIVE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PENDING_REMOVAL', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4897,
+  serialized_end=5033,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
+
+ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
+_CONFIGACTIONENUM = _descriptor.EnumDescriptor(
+  name='ConfigActionEnum',
+  full_name='context.ConfigActionEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_SET', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_DELETE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5177,
+  serialized_end=5270,
+)
+_sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
+
+ConfigActionEnum = enum_type_wrapper.EnumTypeWrapper(_CONFIGACTIONENUM)
+EVENTTYPE_UNDEFINED = 0
+EVENTTYPE_CREATE = 1
+EVENTTYPE_UPDATE = 2
+EVENTTYPE_REMOVE = 3
+DEVICEDRIVER_UNDEFINED = 0
+DEVICEDRIVER_OPENCONFIG = 1
+DEVICEDRIVER_TRANSPORT_API = 2
+DEVICEDRIVER_P4 = 3
+DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4
+DEVICEDRIVER_ONF_TR_352 = 5
+DEVICEOPERATIONALSTATUS_UNDEFINED = 0
+DEVICEOPERATIONALSTATUS_DISABLED = 1
+DEVICEOPERATIONALSTATUS_ENABLED = 2
+SERVICETYPE_UNKNOWN = 0
+SERVICETYPE_L3NM = 1
+SERVICETYPE_L2NM = 2
+SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3
+SERVICESTATUS_UNDEFINED = 0
+SERVICESTATUS_PLANNED = 1
+SERVICESTATUS_ACTIVE = 2
+SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
+CONFIGACTION_UNDEFINED = 0
+CONFIGACTION_SET = 1
+CONFIGACTION_DELETE = 2
+
+
+
+_EMPTY = _descriptor.Descriptor(
+  name='Empty',
+  full_name='context.Empty',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=50,
+  serialized_end=57,
+)
+
+
+_UUID = _descriptor.Descriptor(
+  name='Uuid',
+  full_name='context.Uuid',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='uuid', full_name='context.Uuid.uuid', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=59,
+  serialized_end=79,
+)
+
+
+_EVENT = _descriptor.Descriptor(
+  name='Event',
+  full_name='context.Event',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='context.Event.timestamp', index=0,
+      number=1, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='event_type', full_name='context.Event.event_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=81,
+  serialized_end=151,
+)
+
+
+_CONTEXTID = _descriptor.Descriptor(
+  name='ContextId',
+  full_name='context.ContextId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_uuid', full_name='context.ContextId.context_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=153,
+  serialized_end=201,
+)
+
+
+_CONTEXT = _descriptor.Descriptor(
+  name='Context',
+  full_name='context.Context',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.Context.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.Context.topology_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.Context.service_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='controller', full_name='context.Context.controller', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=204,
+  serialized_end=386,
+)
+
+
+_CONTEXTIDLIST = _descriptor.Descriptor(
+  name='ContextIdList',
+  full_name='context.ContextIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_ids', full_name='context.ContextIdList.context_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=388,
+  serialized_end=444,
+)
+
+
+_CONTEXTLIST = _descriptor.Descriptor(
+  name='ContextList',
+  full_name='context.ContextList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contexts', full_name='context.ContextList.contexts', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=446,
+  serialized_end=495,
+)
+
+
+_CONTEXTEVENT = _descriptor.Descriptor(
+  name='ContextEvent',
+  full_name='context.ContextEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ContextEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ContextEvent.context_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=497,
+  serialized_end=582,
+)
+
+
+_TOPOLOGYID = _descriptor.Descriptor(
+  name='TopologyId',
+  full_name='context.TopologyId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TopologyId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_uuid', full_name='context.TopologyId.topology_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=584,
+  serialized_end=674,
+)
+
+
+_TOPOLOGY = _descriptor.Descriptor(
+  name='Topology',
+  full_name='context.Topology',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.Topology.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.Topology.device_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.Topology.link_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=676,
+  serialized_end=802,
+)
+
+
+_TOPOLOGYIDLIST = _descriptor.Descriptor(
+  name='TopologyIdList',
+  full_name='context.TopologyIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.TopologyIdList.topology_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=804,
+  serialized_end=863,
+)
+
+
+_TOPOLOGYLIST = _descriptor.Descriptor(
+  name='TopologyList',
+  full_name='context.TopologyList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topologies', full_name='context.TopologyList.topologies', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=865,
+  serialized_end=918,
+)
+
+
+_TOPOLOGYEVENT = _descriptor.Descriptor(
+  name='TopologyEvent',
+  full_name='context.TopologyEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.TopologyEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.TopologyEvent.topology_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=920,
+  serialized_end=1008,
+)
+
+
+_DEVICEID = _descriptor.Descriptor(
+  name='DeviceId',
+  full_name='context.DeviceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_uuid', full_name='context.DeviceId.device_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1010,
+  serialized_end=1056,
+)
+
+
+_DEVICE = _descriptor.Descriptor(
+  name='Device',
+  full_name='context.Device',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.Device.device_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_type', full_name='context.Device.device_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_config', full_name='context.Device.device_config', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_operational_status', full_name='context.Device.device_operational_status', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_drivers', full_name='context.Device.device_drivers', index=4,
+      number=5, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_endpoints', full_name='context.Device.device_endpoints', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1059,
+  serialized_end=1341,
+)
+
+
+_DEVICECONFIG = _descriptor.Descriptor(
+  name='DeviceConfig',
+  full_name='context.DeviceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.DeviceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1343,
+  serialized_end=1400,
+)
+
+
+_DEVICEIDLIST = _descriptor.Descriptor(
+  name='DeviceIdList',
+  full_name='context.DeviceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.DeviceIdList.device_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1402,
+  serialized_end=1455,
+)
+
+
+_DEVICELIST = _descriptor.Descriptor(
+  name='DeviceList',
+  full_name='context.DeviceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='devices', full_name='context.DeviceList.devices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1457,
+  serialized_end=1503,
+)
+
+
+_DEVICEEVENT = _descriptor.Descriptor(
+  name='DeviceEvent',
+  full_name='context.DeviceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.DeviceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.DeviceEvent.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1505,
+  serialized_end=1587,
+)
+
+
+_LINKID = _descriptor.Descriptor(
+  name='LinkId',
+  full_name='context.LinkId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_uuid', full_name='context.LinkId.link_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1589,
+  serialized_end=1631,
+)
+
+
+_LINK = _descriptor.Descriptor(
+  name='Link',
+  full_name='context.Link',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.Link.link_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_endpoint_ids', full_name='context.Link.link_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1633,
+  serialized_end=1721,
+)
+
+
+_LINKIDLIST = _descriptor.Descriptor(
+  name='LinkIdList',
+  full_name='context.LinkIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.LinkIdList.link_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1723,
+  serialized_end=1770,
+)
+
+
+_LINKLIST = _descriptor.Descriptor(
+  name='LinkList',
+  full_name='context.LinkList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='links', full_name='context.LinkList.links', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1772,
+  serialized_end=1812,
+)
+
+
+_LINKEVENT = _descriptor.Descriptor(
+  name='LinkEvent',
+  full_name='context.LinkEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.LinkEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.LinkEvent.link_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1814,
+  serialized_end=1890,
+)
+
+
+_SERVICEID = _descriptor.Descriptor(
+  name='ServiceId',
+  full_name='context.ServiceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ServiceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_uuid', full_name='context.ServiceId.service_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1892,
+  serialized_end=1980,
+)
+
+
+_SERVICE = _descriptor.Descriptor(
+  name='Service',
+  full_name='context.Service',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Service.service_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_type', full_name='context.Service.service_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_endpoint_ids', full_name='context.Service.service_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_constraints', full_name='context.Service.service_constraints', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.Service.service_status', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_config', full_name='context.Service.service_config', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1983,
+  serialized_end=2277,
+)
+
+
+_SERVICESTATUS = _descriptor.Descriptor(
+  name='ServiceStatus',
+  full_name='context.ServiceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.ServiceStatus.service_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2279,
+  serialized_end=2346,
+)
+
+
+_SERVICECONFIG = _descriptor.Descriptor(
+  name='ServiceConfig',
+  full_name='context.ServiceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.ServiceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2348,
+  serialized_end=2406,
+)
+
+
+_SERVICEIDLIST = _descriptor.Descriptor(
+  name='ServiceIdList',
+  full_name='context.ServiceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.ServiceIdList.service_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2408,
+  serialized_end=2464,
+)
+
+
+_SERVICELIST = _descriptor.Descriptor(
+  name='ServiceList',
+  full_name='context.ServiceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='services', full_name='context.ServiceList.services', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2466,
+  serialized_end=2515,
+)
+
+
+_SERVICEEVENT = _descriptor.Descriptor(
+  name='ServiceEvent',
+  full_name='context.ServiceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ServiceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.ServiceEvent.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2517,
+  serialized_end=2602,
+)
+
+
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
+_CONNECTIONID = _descriptor.Descriptor(
+  name='ConnectionId',
+  full_name='context.ConnectionId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_uuid', full_name='context.ConnectionId.connection_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3211,
+  serialized_end=3265,
+)
+
+
+_CONNECTION = _descriptor.Descriptor(
+  name='Connection',
+  full_name='context.Connection',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.Connection.connection_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Connection.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='path_hops_endpoint_ids', full_name='context.Connection.path_hops_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='sub_service_ids', full_name='context.Connection.sub_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3268,
+  serialized_end=3464,
+)
+
+
+_CONNECTIONIDLIST = _descriptor.Descriptor(
+  name='ConnectionIdList',
+  full_name='context.ConnectionIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_ids', full_name='context.ConnectionIdList.connection_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3466,
+  serialized_end=3531,
+)
+
+
+_CONNECTIONLIST = _descriptor.Descriptor(
+  name='ConnectionList',
+  full_name='context.ConnectionList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connections', full_name='context.ConnectionList.connections', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3533,
+  serialized_end=3591,
+)
+
+
+_CONNECTIONEVENT = _descriptor.Descriptor(
+  name='ConnectionEvent',
+  full_name='context.ConnectionEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ConnectionEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.ConnectionEvent.connection_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3593,
+  serialized_end=3687,
+)
+
+
+_ENDPOINTID = _descriptor.Descriptor(
+  name='EndPointId',
+  full_name='context.EndPointId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.EndPointId.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.EndPointId.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_uuid', full_name='context.EndPointId.endpoint_uuid', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3690,
+  serialized_end=3820,
+)
+
+
+_ENDPOINT = _descriptor.Descriptor(
+  name='EndPoint',
+  full_name='context.EndPoint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='endpoint_id', full_name='context.EndPoint.endpoint_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_type', full_name='context.EndPoint.endpoint_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='kpi_sample_types', full_name='context.EndPoint.kpi_sample_types', index=2,
+      number=3, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3823,
+  serialized_end=3957,
+)
+
+
+_CONFIGRULE = _descriptor.Descriptor(
+  name='ConfigRule',
+  full_name='context.ConfigRule',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='action', full_name='context.ConfigRule.action', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_key', full_name='context.ConfigRule.resource_key', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_value', full_name='context.ConfigRule.resource_value', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3959,
+  serialized_end=4060,
+)
+
+
+_CONSTRAINT = _descriptor.Descriptor(
+  name='Constraint',
+  full_name='context.Constraint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='constraint_type', full_name='context.Constraint.constraint_type', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='constraint_value', full_name='context.Constraint.constraint_value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4062,
+  serialized_end=4125,
+)
+
+
+_TERAFLOWCONTROLLER = _descriptor.Descriptor(
+  name='TeraFlowController',
+  full_name='context.TeraFlowController',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TeraFlowController.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='ip_address', full_name='context.TeraFlowController.ip_address', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='port', full_name='context.TeraFlowController.port', index=2,
+      number=3, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4127,
+  serialized_end=4221,
+)
+
+
+_AUTHENTICATIONRESULT = _descriptor.Descriptor(
+  name='AuthenticationResult',
+  full_name='context.AuthenticationResult',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.AuthenticationResult.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='authenticated', full_name='context.AuthenticationResult.authenticated', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4223,
+  serialized_end=4308,
+)
+
+_EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
+_CONTEXTID.fields_by_name['context_uuid'].message_type = _UUID
+_CONTEXT.fields_by_name['context_id'].message_type = _CONTEXTID
+_CONTEXT.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_CONTEXT.fields_by_name['service_ids'].message_type = _SERVICEID
+_CONTEXT.fields_by_name['controller'].message_type = _TERAFLOWCONTROLLER
+_CONTEXTIDLIST.fields_by_name['context_ids'].message_type = _CONTEXTID
+_CONTEXTLIST.fields_by_name['contexts'].message_type = _CONTEXT
+_CONTEXTEVENT.fields_by_name['event'].message_type = _EVENT
+_CONTEXTEVENT.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['topology_uuid'].message_type = _UUID
+_TOPOLOGY.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_TOPOLOGY.fields_by_name['device_ids'].message_type = _DEVICEID
+_TOPOLOGY.fields_by_name['link_ids'].message_type = _LINKID
+_TOPOLOGYIDLIST.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_TOPOLOGYLIST.fields_by_name['topologies'].message_type = _TOPOLOGY
+_TOPOLOGYEVENT.fields_by_name['event'].message_type = _EVENT
+_TOPOLOGYEVENT.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_DEVICEID.fields_by_name['device_uuid'].message_type = _UUID
+_DEVICE.fields_by_name['device_id'].message_type = _DEVICEID
+_DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG
+_DEVICE.fields_by_name['device_operational_status'].enum_type = _DEVICEOPERATIONALSTATUSENUM
+_DEVICE.fields_by_name['device_drivers'].enum_type = _DEVICEDRIVERENUM
+_DEVICE.fields_by_name['device_endpoints'].message_type = _ENDPOINT
+_DEVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_DEVICEIDLIST.fields_by_name['device_ids'].message_type = _DEVICEID
+_DEVICELIST.fields_by_name['devices'].message_type = _DEVICE
+_DEVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_DEVICEEVENT.fields_by_name['device_id'].message_type = _DEVICEID
+_LINKID.fields_by_name['link_uuid'].message_type = _UUID
+_LINK.fields_by_name['link_id'].message_type = _LINKID
+_LINK.fields_by_name['link_endpoint_ids'].message_type = _ENDPOINTID
+_LINKIDLIST.fields_by_name['link_ids'].message_type = _LINKID
+_LINKLIST.fields_by_name['links'].message_type = _LINK
+_LINKEVENT.fields_by_name['event'].message_type = _EVENT
+_LINKEVENT.fields_by_name['link_id'].message_type = _LINKID
+_SERVICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SERVICEID.fields_by_name['service_uuid'].message_type = _UUID
+_SERVICE.fields_by_name['service_id'].message_type = _SERVICEID
+_SERVICE.fields_by_name['service_type'].enum_type = _SERVICETYPEENUM
+_SERVICE.fields_by_name['service_endpoint_ids'].message_type = _ENDPOINTID
+_SERVICE.fields_by_name['service_constraints'].message_type = _CONSTRAINT
+_SERVICE.fields_by_name['service_status'].message_type = _SERVICESTATUS
+_SERVICE.fields_by_name['service_config'].message_type = _SERVICECONFIG
+_SERVICESTATUS.fields_by_name['service_status'].enum_type = _SERVICESTATUSENUM
+_SERVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
+_SERVICELIST.fields_by_name['services'].message_type = _SERVICE
+_SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
+_CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
+_CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
+_CONNECTION.fields_by_name['path_hops_endpoint_ids'].message_type = _ENDPOINTID
+_CONNECTION.fields_by_name['sub_service_ids'].message_type = _SERVICEID
+_CONNECTIONIDLIST.fields_by_name['connection_ids'].message_type = _CONNECTIONID
+_CONNECTIONLIST.fields_by_name['connections'].message_type = _CONNECTION
+_CONNECTIONEVENT.fields_by_name['event'].message_type = _EVENT
+_CONNECTIONEVENT.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_ENDPOINTID.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID
+_ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID
+_ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID
+_ENDPOINT.fields_by_name['kpi_sample_types'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE
+_CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM
+_TERAFLOWCONTROLLER.fields_by_name['context_id'].message_type = _CONTEXTID
+_AUTHENTICATIONRESULT.fields_by_name['context_id'].message_type = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
+DESCRIPTOR.message_types_by_name['Uuid'] = _UUID
+DESCRIPTOR.message_types_by_name['Event'] = _EVENT
+DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT
+DESCRIPTOR.message_types_by_name['ContextIdList'] = _CONTEXTIDLIST
+DESCRIPTOR.message_types_by_name['ContextList'] = _CONTEXTLIST
+DESCRIPTOR.message_types_by_name['ContextEvent'] = _CONTEXTEVENT
+DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID
+DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY
+DESCRIPTOR.message_types_by_name['TopologyIdList'] = _TOPOLOGYIDLIST
+DESCRIPTOR.message_types_by_name['TopologyList'] = _TOPOLOGYLIST
+DESCRIPTOR.message_types_by_name['TopologyEvent'] = _TOPOLOGYEVENT
+DESCRIPTOR.message_types_by_name['DeviceId'] = _DEVICEID
+DESCRIPTOR.message_types_by_name['Device'] = _DEVICE
+DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG
+DESCRIPTOR.message_types_by_name['DeviceIdList'] = _DEVICEIDLIST
+DESCRIPTOR.message_types_by_name['DeviceList'] = _DEVICELIST
+DESCRIPTOR.message_types_by_name['DeviceEvent'] = _DEVICEEVENT
+DESCRIPTOR.message_types_by_name['LinkId'] = _LINKID
+DESCRIPTOR.message_types_by_name['Link'] = _LINK
+DESCRIPTOR.message_types_by_name['LinkIdList'] = _LINKIDLIST
+DESCRIPTOR.message_types_by_name['LinkList'] = _LINKLIST
+DESCRIPTOR.message_types_by_name['LinkEvent'] = _LINKEVENT
+DESCRIPTOR.message_types_by_name['ServiceId'] = _SERVICEID
+DESCRIPTOR.message_types_by_name['Service'] = _SERVICE
+DESCRIPTOR.message_types_by_name['ServiceStatus'] = _SERVICESTATUS
+DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
+DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
+DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
+DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
+DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
+DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
+DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
+DESCRIPTOR.message_types_by_name['ConnectionList'] = _CONNECTIONLIST
+DESCRIPTOR.message_types_by_name['ConnectionEvent'] = _CONNECTIONEVENT
+DESCRIPTOR.message_types_by_name['EndPointId'] = _ENDPOINTID
+DESCRIPTOR.message_types_by_name['EndPoint'] = _ENDPOINT
+DESCRIPTOR.message_types_by_name['ConfigRule'] = _CONFIGRULE
+DESCRIPTOR.message_types_by_name['Constraint'] = _CONSTRAINT
+DESCRIPTOR.message_types_by_name['TeraFlowController'] = _TERAFLOWCONTROLLER
+DESCRIPTOR.message_types_by_name['AuthenticationResult'] = _AUTHENTICATIONRESULT
+DESCRIPTOR.enum_types_by_name['EventTypeEnum'] = _EVENTTYPEENUM
+DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
+DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
+DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
+DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
+  'DESCRIPTOR' : _EMPTY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Empty)
+  })
+_sym_db.RegisterMessage(Empty)
+
+Uuid = _reflection.GeneratedProtocolMessageType('Uuid', (_message.Message,), {
+  'DESCRIPTOR' : _UUID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Uuid)
+  })
+_sym_db.RegisterMessage(Uuid)
+
+Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), {
+  'DESCRIPTOR' : _EVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Event)
+  })
+_sym_db.RegisterMessage(Event)
+
+ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextId)
+  })
+_sym_db.RegisterMessage(ContextId)
+
+Context = _reflection.GeneratedProtocolMessageType('Context', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Context)
+  })
+_sym_db.RegisterMessage(Context)
+
+ContextIdList = _reflection.GeneratedProtocolMessageType('ContextIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextIdList)
+  })
+_sym_db.RegisterMessage(ContextIdList)
+
+ContextList = _reflection.GeneratedProtocolMessageType('ContextList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextList)
+  })
+_sym_db.RegisterMessage(ContextList)
+
+ContextEvent = _reflection.GeneratedProtocolMessageType('ContextEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextEvent)
+  })
+_sym_db.RegisterMessage(ContextEvent)
+
+TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyId)
+  })
+_sym_db.RegisterMessage(TopologyId)
+
+Topology = _reflection.GeneratedProtocolMessageType('Topology', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Topology)
+  })
+_sym_db.RegisterMessage(Topology)
+
+TopologyIdList = _reflection.GeneratedProtocolMessageType('TopologyIdList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyIdList)
+  })
+_sym_db.RegisterMessage(TopologyIdList)
+
+TopologyList = _reflection.GeneratedProtocolMessageType('TopologyList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyList)
+  })
+_sym_db.RegisterMessage(TopologyList)
+
+TopologyEvent = _reflection.GeneratedProtocolMessageType('TopologyEvent', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyEvent)
+  })
+_sym_db.RegisterMessage(TopologyEvent)
+
+DeviceId = _reflection.GeneratedProtocolMessageType('DeviceId', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceId)
+  })
+_sym_db.RegisterMessage(DeviceId)
+
+Device = _reflection.GeneratedProtocolMessageType('Device', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Device)
+  })
+_sym_db.RegisterMessage(Device)
+
+DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceConfig)
+  })
+_sym_db.RegisterMessage(DeviceConfig)
+
+DeviceIdList = _reflection.GeneratedProtocolMessageType('DeviceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceIdList)
+  })
+_sym_db.RegisterMessage(DeviceIdList)
+
+DeviceList = _reflection.GeneratedProtocolMessageType('DeviceList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceList)
+  })
+_sym_db.RegisterMessage(DeviceList)
+
+DeviceEvent = _reflection.GeneratedProtocolMessageType('DeviceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceEvent)
+  })
+_sym_db.RegisterMessage(DeviceEvent)
+
+LinkId = _reflection.GeneratedProtocolMessageType('LinkId', (_message.Message,), {
+  'DESCRIPTOR' : _LINKID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkId)
+  })
+_sym_db.RegisterMessage(LinkId)
+
+Link = _reflection.GeneratedProtocolMessageType('Link', (_message.Message,), {
+  'DESCRIPTOR' : _LINK,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Link)
+  })
+_sym_db.RegisterMessage(Link)
+
+LinkIdList = _reflection.GeneratedProtocolMessageType('LinkIdList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkIdList)
+  })
+_sym_db.RegisterMessage(LinkIdList)
+
+LinkList = _reflection.GeneratedProtocolMessageType('LinkList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkList)
+  })
+_sym_db.RegisterMessage(LinkList)
+
+LinkEvent = _reflection.GeneratedProtocolMessageType('LinkEvent', (_message.Message,), {
+  'DESCRIPTOR' : _LINKEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkEvent)
+  })
+_sym_db.RegisterMessage(LinkEvent)
+
+ServiceId = _reflection.GeneratedProtocolMessageType('ServiceId', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceId)
+  })
+_sym_db.RegisterMessage(ServiceId)
+
+Service = _reflection.GeneratedProtocolMessageType('Service', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Service)
+  })
+_sym_db.RegisterMessage(Service)
+
+ServiceStatus = _reflection.GeneratedProtocolMessageType('ServiceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceStatus)
+  })
+_sym_db.RegisterMessage(ServiceStatus)
+
+ServiceConfig = _reflection.GeneratedProtocolMessageType('ServiceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceConfig)
+  })
+_sym_db.RegisterMessage(ServiceConfig)
+
+ServiceIdList = _reflection.GeneratedProtocolMessageType('ServiceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceIdList)
+  })
+_sym_db.RegisterMessage(ServiceIdList)
+
+ServiceList = _reflection.GeneratedProtocolMessageType('ServiceList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceList)
+  })
+_sym_db.RegisterMessage(ServiceList)
+
+ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceEvent)
+  })
+_sym_db.RegisterMessage(ServiceEvent)
+
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
+ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionId)
+  })
+_sym_db.RegisterMessage(ConnectionId)
+
+Connection = _reflection.GeneratedProtocolMessageType('Connection', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTION,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Connection)
+  })
+_sym_db.RegisterMessage(Connection)
+
+ConnectionIdList = _reflection.GeneratedProtocolMessageType('ConnectionIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionIdList)
+  })
+_sym_db.RegisterMessage(ConnectionIdList)
+
+ConnectionList = _reflection.GeneratedProtocolMessageType('ConnectionList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionList)
+  })
+_sym_db.RegisterMessage(ConnectionList)
+
+ConnectionEvent = _reflection.GeneratedProtocolMessageType('ConnectionEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionEvent)
+  })
+_sym_db.RegisterMessage(ConnectionEvent)
+
+EndPointId = _reflection.GeneratedProtocolMessageType('EndPointId', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPointId)
+  })
+_sym_db.RegisterMessage(EndPointId)
+
+EndPoint = _reflection.GeneratedProtocolMessageType('EndPoint', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPoint)
+  })
+_sym_db.RegisterMessage(EndPoint)
+
+ConfigRule = _reflection.GeneratedProtocolMessageType('ConfigRule', (_message.Message,), {
+  'DESCRIPTOR' : _CONFIGRULE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConfigRule)
+  })
+_sym_db.RegisterMessage(ConfigRule)
+
+Constraint = _reflection.GeneratedProtocolMessageType('Constraint', (_message.Message,), {
+  'DESCRIPTOR' : _CONSTRAINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Constraint)
+  })
+_sym_db.RegisterMessage(Constraint)
+
+TeraFlowController = _reflection.GeneratedProtocolMessageType('TeraFlowController', (_message.Message,), {
+  'DESCRIPTOR' : _TERAFLOWCONTROLLER,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TeraFlowController)
+  })
+_sym_db.RegisterMessage(TeraFlowController)
+
+AuthenticationResult = _reflection.GeneratedProtocolMessageType('AuthenticationResult', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHENTICATIONRESULT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.AuthenticationResult)
+  })
+_sym_db.RegisterMessage(AuthenticationResult)
+
+
+
+_CONTEXTSERVICE = _descriptor.ServiceDescriptor(
+  name='ContextService',
+  full_name='context.ContextService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=5273,
+  serialized_end=7688,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='ListContextIds',
+    full_name='context.ContextService.ListContextIds',
+    index=0,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListContexts',
+    full_name='context.ContextService.ListContexts',
+    index=1,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContext',
+    full_name='context.ContextService.GetContext',
+    index=2,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_CONTEXT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetContext',
+    full_name='context.ContextService.SetContext',
+    index=3,
+    containing_service=None,
+    input_type=_CONTEXT,
+    output_type=_CONTEXTID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveContext',
+    full_name='context.ContextService.RemoveContext',
+    index=4,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContextEvents',
+    full_name='context.ContextService.GetContextEvents',
+    index=5,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologyIds',
+    full_name='context.ContextService.ListTopologyIds',
+    index=6,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologies',
+    full_name='context.ContextService.ListTopologies',
+    index=7,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopology',
+    full_name='context.ContextService.GetTopology',
+    index=8,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_TOPOLOGY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetTopology',
+    full_name='context.ContextService.SetTopology',
+    index=9,
+    containing_service=None,
+    input_type=_TOPOLOGY,
+    output_type=_TOPOLOGYID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveTopology',
+    full_name='context.ContextService.RemoveTopology',
+    index=10,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopologyEvents',
+    full_name='context.ContextService.GetTopologyEvents',
+    index=11,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_TOPOLOGYEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDeviceIds',
+    full_name='context.ContextService.ListDeviceIds',
+    index=12,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDevices',
+    full_name='context.ContextService.ListDevices',
+    index=13,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDevice',
+    full_name='context.ContextService.GetDevice',
+    index=14,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_DEVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetDevice',
+    full_name='context.ContextService.SetDevice',
+    index=15,
+    containing_service=None,
+    input_type=_DEVICE,
+    output_type=_DEVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveDevice',
+    full_name='context.ContextService.RemoveDevice',
+    index=16,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDeviceEvents',
+    full_name='context.ContextService.GetDeviceEvents',
+    index=17,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinkIds',
+    full_name='context.ContextService.ListLinkIds',
+    index=18,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinks',
+    full_name='context.ContextService.ListLinks',
+    index=19,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLink',
+    full_name='context.ContextService.GetLink',
+    index=20,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_LINK,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetLink',
+    full_name='context.ContextService.SetLink',
+    index=21,
+    containing_service=None,
+    input_type=_LINK,
+    output_type=_LINKID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveLink',
+    full_name='context.ContextService.RemoveLink',
+    index=22,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLinkEvents',
+    full_name='context.ContextService.GetLinkEvents',
+    index=23,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServiceIds',
+    full_name='context.ContextService.ListServiceIds',
+    index=24,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServices',
+    full_name='context.ContextService.ListServices',
+    index=25,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetService',
+    full_name='context.ContextService.GetService',
+    index=26,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_SERVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetService',
+    full_name='context.ContextService.SetService',
+    index=27,
+    containing_service=None,
+    input_type=_SERVICE,
+    output_type=_SERVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveService',
+    full_name='context.ContextService.RemoveService',
+    index=28,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetServiceEvents',
+    full_name='context.ContextService.GetServiceEvents',
+    index=29,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SERVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnectionIds',
+    full_name='context.ContextService.ListConnectionIds',
+    index=36,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnections',
+    full_name='context.ContextService.ListConnections',
+    index=37,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnection',
+    full_name='context.ContextService.GetConnection',
+    index=38,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_CONNECTION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetConnection',
+    full_name='context.ContextService.SetConnection',
+    index=39,
+    containing_service=None,
+    input_type=_CONNECTION,
+    output_type=_CONNECTIONID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveConnection',
+    full_name='context.ContextService.RemoveConnection',
+    index=40,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnectionEvents',
+    full_name='context.ContextService.GetConnectionEvents',
+    index=41,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONNECTIONEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CONTEXTSERVICE)
+
+DESCRIPTOR.services_by_name['ContextService'] = _CONTEXTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/l3_attackmitigator/proto/kpi_sample_types_pb2.py b/src/l3_attackmitigator/proto/kpi_sample_types_pb2.py
new file mode 100644
index 000000000..ea7fd2f82
--- /dev/null
+++ b/src/l3_attackmitigator/proto/kpi_sample_types_pb2.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: kpi_sample_types.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='kpi_sample_types.proto',
+  package='kpi_sample_types',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*\xbe\x01\n\rKpiSampleType\x12\x19\n\x15KPISAMPLETYPE_UNKNOWN\x10\x00\x12%\n!KPISAMPLETYPE_PACKETS_TRANSMITTED\x10\x65\x12\"\n\x1eKPISAMPLETYPE_PACKETS_RECEIVED\x10\x66\x12$\n\x1fKPISAMPLETYPE_BYTES_TRANSMITTED\x10\xc9\x01\x12!\n\x1cKPISAMPLETYPE_BYTES_RECEIVED\x10\xca\x01\x62\x06proto3'
+)
+
+_KPISAMPLETYPE = _descriptor.EnumDescriptor(
+  name='KpiSampleType',
+  full_name='kpi_sample_types.KpiSampleType',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_TRANSMITTED', index=1, number=101,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_RECEIVED', index=2, number=102,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_TRANSMITTED', index=3, number=201,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_RECEIVED', index=4, number=202,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=45,
+  serialized_end=235,
+)
+_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE)
+
+KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE)
+KPISAMPLETYPE_UNKNOWN = 0
+KPISAMPLETYPE_PACKETS_TRANSMITTED = 101
+KPISAMPLETYPE_PACKETS_RECEIVED = 102
+KPISAMPLETYPE_BYTES_TRANSMITTED = 201
+KPISAMPLETYPE_BYTES_RECEIVED = 202
+
+
+DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/l3_attackmitigator/proto/l3_attackmitigator_pb2.py b/src/l3_attackmitigator/proto/l3_attackmitigator_pb2.py
index 0ad49c2ed..e148d0a2c 100644
--- a/src/l3_attackmitigator/proto/l3_attackmitigator_pb2.py
+++ b/src/l3_attackmitigator/proto/l3_attackmitigator_pb2.py
@@ -11,6 +11,7 @@ from google.protobuf import symbol_database as _symbol_database
 _sym_db = _symbol_database.Default()
 
 
+from . import context_pb2 as context__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
@@ -19,129 +20,93 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x18l3_attackmitigator.proto\"2\n\x0e\x45mptyMitigator\x12\x14\n\x07message\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_message\"\xf9\x01\n\x06Output\x12\x12\n\nconfidence\x18\x01 \x01(\x02\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x0c\n\x04ip_o\x18\x03 \x01(\t\x12\x10\n\x08tag_name\x18\x04 \x01(\t\x12\x0b\n\x03tag\x18\x05 \x01(\x05\x12\x0f\n\x07\x66low_id\x18\x06 \x01(\t\x12\x10\n\x08protocol\x18\x07 \x01(\t\x12\x0e\n\x06port_d\x18\x08 \x01(\t\x12\x12\n\x05ml_id\x18\t \x01(\tH\x00\x88\x01\x01\x12\x17\n\ntime_start\x18\n \x01(\x02H\x01\x88\x01\x01\x12\x15\n\x08time_end\x18\x0b \x01(\x02H\x02\x88\x01\x01\x42\x08\n\x06_ml_idB\r\n\x0b_time_startB\x0b\n\t_time_end2r\n\x11L3Attackmitigator\x12(\n\nSendOutput\x12\x07.Output\x1a\x0f.EmptyMitigator\"\x00\x12\x33\n\rGetMitigation\x12\x0f.EmptyMitigator\x1a\x0f.EmptyMitigator\"\x00\x62\x06proto3'
-)
+  serialized_pb=b'\n\x18l3_attackmitigator.proto\x1a\rcontext.proto\"\xd5\x01\n\x17L3AttackmitigatorOutput\x12\x12\n\nconfidence\x18\x01 \x01(\x02\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x0c\n\x04ip_o\x18\x03 \x01(\t\x12\x10\n\x08tag_name\x18\x04 \x01(\t\x12\x0b\n\x03tag\x18\x05 \x01(\x05\x12\x0f\n\x07\x66low_id\x18\x06 \x01(\t\x12\x10\n\x08protocol\x18\x07 \x01(\t\x12\x0e\n\x06port_d\x18\x08 \x01(\t\x12\r\n\x05ml_id\x18\t \x01(\t\x12\x12\n\ntime_start\x18\n \x01(\x02\x12\x10\n\x08time_end\x18\x0b \x01(\x02\x32\x80\x01\n\x11L3Attackmitigator\x12\x38\n\nSendOutput\x12\x18.L3AttackmitigatorOutput\x1a\x0e.context.Empty\"\x00\x12\x31\n\rGetMitigation\x12\x0e.context.Empty\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
+  ,
+  dependencies=[context__pb2.DESCRIPTOR,])
 
 
 
 
-_EMPTYMITIGATOR = _descriptor.Descriptor(
-  name='EmptyMitigator',
-  full_name='EmptyMitigator',
+_L3ATTACKMITIGATOROUTPUT = _descriptor.Descriptor(
+  name='L3AttackmitigatorOutput',
+  full_name='L3AttackmitigatorOutput',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='message', full_name='EmptyMitigator.message', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  serialized_options=None,
-  is_extendable=False,
-  syntax='proto3',
-  extension_ranges=[],
-  oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_message', full_name='EmptyMitigator._message',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-  ],
-  serialized_start=28,
-  serialized_end=78,
-)
-
-
-_OUTPUT = _descriptor.Descriptor(
-  name='Output',
-  full_name='Output',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  create_key=_descriptor._internal_create_key,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='confidence', full_name='Output.confidence', index=0,
+      name='confidence', full_name='L3AttackmitigatorOutput.confidence', index=0,
       number=1, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='timestamp', full_name='Output.timestamp', index=1,
+      name='timestamp', full_name='L3AttackmitigatorOutput.timestamp', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ip_o', full_name='Output.ip_o', index=2,
+      name='ip_o', full_name='L3AttackmitigatorOutput.ip_o', index=2,
       number=3, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='tag_name', full_name='Output.tag_name', index=3,
+      name='tag_name', full_name='L3AttackmitigatorOutput.tag_name', index=3,
       number=4, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='tag', full_name='Output.tag', index=4,
+      name='tag', full_name='L3AttackmitigatorOutput.tag', index=4,
       number=5, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='flow_id', full_name='Output.flow_id', index=5,
+      name='flow_id', full_name='L3AttackmitigatorOutput.flow_id', index=5,
       number=6, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='protocol', full_name='Output.protocol', index=6,
+      name='protocol', full_name='L3AttackmitigatorOutput.protocol', index=6,
       number=7, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='port_d', full_name='Output.port_d', index=7,
+      name='port_d', full_name='L3AttackmitigatorOutput.port_d', index=7,
       number=8, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ml_id', full_name='Output.ml_id', index=8,
+      name='ml_id', full_name='L3AttackmitigatorOutput.ml_id', index=8,
       number=9, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_start', full_name='Output.time_start', index=9,
+      name='time_start', full_name='L3AttackmitigatorOutput.time_start', index=9,
       number=10, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_end', full_name='Output.time_end', index=10,
+      name='time_end', full_name='L3AttackmitigatorOutput.time_end', index=10,
       number=11, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
@@ -158,55 +123,20 @@ _OUTPUT = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_ml_id', full_name='Output._ml_id',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_start', full_name='Output._time_start',
-      index=1, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_end', full_name='Output._time_end',
-      index=2, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
   ],
-  serialized_start=81,
-  serialized_end=330,
+  serialized_start=44,
+  serialized_end=257,
 )
 
-_EMPTYMITIGATOR.oneofs_by_name['_message'].fields.append(
-  _EMPTYMITIGATOR.fields_by_name['message'])
-_EMPTYMITIGATOR.fields_by_name['message'].containing_oneof = _EMPTYMITIGATOR.oneofs_by_name['_message']
-_OUTPUT.oneofs_by_name['_ml_id'].fields.append(
-  _OUTPUT.fields_by_name['ml_id'])
-_OUTPUT.fields_by_name['ml_id'].containing_oneof = _OUTPUT.oneofs_by_name['_ml_id']
-_OUTPUT.oneofs_by_name['_time_start'].fields.append(
-  _OUTPUT.fields_by_name['time_start'])
-_OUTPUT.fields_by_name['time_start'].containing_oneof = _OUTPUT.oneofs_by_name['_time_start']
-_OUTPUT.oneofs_by_name['_time_end'].fields.append(
-  _OUTPUT.fields_by_name['time_end'])
-_OUTPUT.fields_by_name['time_end'].containing_oneof = _OUTPUT.oneofs_by_name['_time_end']
-DESCRIPTOR.message_types_by_name['EmptyMitigator'] = _EMPTYMITIGATOR
-DESCRIPTOR.message_types_by_name['Output'] = _OUTPUT
+DESCRIPTOR.message_types_by_name['L3AttackmitigatorOutput'] = _L3ATTACKMITIGATOROUTPUT
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
-EmptyMitigator = _reflection.GeneratedProtocolMessageType('EmptyMitigator', (_message.Message,), {
-  'DESCRIPTOR' : _EMPTYMITIGATOR,
-  '__module__' : 'l3_attackmitigator_pb2'
-  # @@protoc_insertion_point(class_scope:EmptyMitigator)
-  })
-_sym_db.RegisterMessage(EmptyMitigator)
-
-Output = _reflection.GeneratedProtocolMessageType('Output', (_message.Message,), {
-  'DESCRIPTOR' : _OUTPUT,
+L3AttackmitigatorOutput = _reflection.GeneratedProtocolMessageType('L3AttackmitigatorOutput', (_message.Message,), {
+  'DESCRIPTOR' : _L3ATTACKMITIGATOROUTPUT,
   '__module__' : 'l3_attackmitigator_pb2'
-  # @@protoc_insertion_point(class_scope:Output)
+  # @@protoc_insertion_point(class_scope:L3AttackmitigatorOutput)
   })
-_sym_db.RegisterMessage(Output)
+_sym_db.RegisterMessage(L3AttackmitigatorOutput)
 
 
 
@@ -217,16 +147,16 @@ _L3ATTACKMITIGATOR = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=332,
-  serialized_end=446,
+  serialized_start=260,
+  serialized_end=388,
   methods=[
   _descriptor.MethodDescriptor(
     name='SendOutput',
     full_name='L3Attackmitigator.SendOutput',
     index=0,
     containing_service=None,
-    input_type=_OUTPUT,
-    output_type=_EMPTYMITIGATOR,
+    input_type=_L3ATTACKMITIGATOROUTPUT,
+    output_type=context__pb2._EMPTY,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
@@ -235,8 +165,8 @@ _L3ATTACKMITIGATOR = _descriptor.ServiceDescriptor(
     full_name='L3Attackmitigator.GetMitigation',
     index=1,
     containing_service=None,
-    input_type=_EMPTYMITIGATOR,
-    output_type=_EMPTYMITIGATOR,
+    input_type=context__pb2._EMPTY,
+    output_type=context__pb2._EMPTY,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
diff --git a/src/l3_attackmitigator/proto/l3_attackmitigator_pb2_grpc.py b/src/l3_attackmitigator/proto/l3_attackmitigator_pb2_grpc.py
index 3942d6843..25d4afdba 100644
--- a/src/l3_attackmitigator/proto/l3_attackmitigator_pb2_grpc.py
+++ b/src/l3_attackmitigator/proto/l3_attackmitigator_pb2_grpc.py
@@ -2,7 +2,7 @@
 """Client and server classes corresponding to protobuf-defined services."""
 import grpc
 
-
+from . import context_pb2 as context__pb2
 from . import l3_attackmitigator_pb2 as l3__attackmitigator__pb2
 
 
@@ -17,13 +17,13 @@ class L3AttackmitigatorStub(object):
         """
         self.SendOutput = channel.unary_unary(
                 '/L3Attackmitigator/SendOutput',
-                request_serializer=l3__attackmitigator__pb2.Output.SerializeToString,
-                response_deserializer=l3__attackmitigator__pb2.EmptyMitigator.FromString,
+                request_serializer=l3__attackmitigator__pb2.L3AttackmitigatorOutput.SerializeToString,
+                response_deserializer=context__pb2.Empty.FromString,
                 )
         self.GetMitigation = channel.unary_unary(
                 '/L3Attackmitigator/GetMitigation',
-                request_serializer=l3__attackmitigator__pb2.EmptyMitigator.SerializeToString,
-                response_deserializer=l3__attackmitigator__pb2.EmptyMitigator.FromString,
+                request_serializer=context__pb2.Empty.SerializeToString,
+                response_deserializer=context__pb2.Empty.FromString,
                 )
 
 
@@ -49,13 +49,13 @@ def add_L3AttackmitigatorServicer_to_server(servicer, server):
     rpc_method_handlers = {
             'SendOutput': grpc.unary_unary_rpc_method_handler(
                     servicer.SendOutput,
-                    request_deserializer=l3__attackmitigator__pb2.Output.FromString,
-                    response_serializer=l3__attackmitigator__pb2.EmptyMitigator.SerializeToString,
+                    request_deserializer=l3__attackmitigator__pb2.L3AttackmitigatorOutput.FromString,
+                    response_serializer=context__pb2.Empty.SerializeToString,
             ),
             'GetMitigation': grpc.unary_unary_rpc_method_handler(
                     servicer.GetMitigation,
-                    request_deserializer=l3__attackmitigator__pb2.EmptyMitigator.FromString,
-                    response_serializer=l3__attackmitigator__pb2.EmptyMitigator.SerializeToString,
+                    request_deserializer=context__pb2.Empty.FromString,
+                    response_serializer=context__pb2.Empty.SerializeToString,
             ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
@@ -79,8 +79,8 @@ class L3Attackmitigator(object):
             timeout=None,
             metadata=None):
         return grpc.experimental.unary_unary(request, target, '/L3Attackmitigator/SendOutput',
-            l3__attackmitigator__pb2.Output.SerializeToString,
-            l3__attackmitigator__pb2.EmptyMitigator.FromString,
+            l3__attackmitigator__pb2.L3AttackmitigatorOutput.SerializeToString,
+            context__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
 
@@ -96,7 +96,7 @@ class L3Attackmitigator(object):
             timeout=None,
             metadata=None):
         return grpc.experimental.unary_unary(request, target, '/L3Attackmitigator/GetMitigation',
-            l3__attackmitigator__pb2.EmptyMitigator.SerializeToString,
-            l3__attackmitigator__pb2.EmptyMitigator.FromString,
+            context__pb2.Empty.SerializeToString,
+            context__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/l3_centralizedattackdetector/genproto.sh b/src/l3_centralizedattackdetector/genproto.sh
old mode 100644
new mode 100755
index a68c8638d..54b16a486
--- a/src/l3_centralizedattackdetector/genproto.sh
+++ b/src/l3_centralizedattackdetector/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,19 +14,39 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
 
-python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto l3_centralizedattackdetector.proto
+EOF
+
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto l3_attackmitigator.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto l3_centralizedattackdetector.proto
+
+rm proto/context_pb2_grpc.py
+rm proto/kpi_sample_types_pb2_grpc.py
+rm proto/l3_attackmitigator_pb2_grpc.py
 
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py
 sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/l3_centralizedattackdetector_pb2.py
 sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/l3_centralizedattackdetector_pb2_grpc.py
 sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/l3_attackmitigator_pb2.py
-sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/l3_attackmitigator_pb2_grpc.py
diff --git a/src/l3_centralizedattackdetector/proto/context_pb2.py b/src/l3_centralizedattackdetector/proto/context_pb2.py
new file mode 100644
index 000000000..50d501d3a
--- /dev/null
+++ b/src/l3_centralizedattackdetector/proto/context_pb2.py
@@ -0,0 +1,3071 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: context.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import kpi_sample_types_pb2 as kpi__sample__types__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='context.proto',
+  package='context',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  ,
+  dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
+
+_EVENTTYPEENUM = _descriptor.EnumDescriptor(
+  name='EventTypeEnum',
+  full_name='context.EventTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_CREATE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UPDATE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_REMOVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4310,
+  serialized_end=4416,
+)
+_sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
+
+EventTypeEnum = enum_type_wrapper.EnumTypeWrapper(_EVENTTYPEENUM)
+_DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
+  name='DeviceDriverEnum',
+  full_name='context.DeviceDriverEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_OPENCONFIG', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_TRANSPORT_API', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_P4', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_IETF_NETWORK_TOPOLOGY', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_ONF_TR_352', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4419,
+  serialized_end=4616,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
+
+DeviceDriverEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEDRIVERENUM)
+_DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
+  name='DeviceOperationalStatusEnum',
+  full_name='context.DeviceOperationalStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_DISABLED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_ENABLED', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4619,
+  serialized_end=4762,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
+
+DeviceOperationalStatusEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEOPERATIONALSTATUSENUM)
+_SERVICETYPEENUM = _descriptor.EnumDescriptor(
+  name='ServiceTypeEnum',
+  full_name='context.ServiceTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L3NM', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L2NM', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_TAPI_CONNECTIVITY_SERVICE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4765,
+  serialized_end=4894,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
+
+ServiceTypeEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPEENUM)
+_SERVICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='ServiceStatusEnum',
+  full_name='context.ServiceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_ACTIVE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PENDING_REMOVAL', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4897,
+  serialized_end=5033,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
+
+ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
+_CONFIGACTIONENUM = _descriptor.EnumDescriptor(
+  name='ConfigActionEnum',
+  full_name='context.ConfigActionEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_SET', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_DELETE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5177,
+  serialized_end=5270,
+)
+_sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
+
+ConfigActionEnum = enum_type_wrapper.EnumTypeWrapper(_CONFIGACTIONENUM)
+EVENTTYPE_UNDEFINED = 0
+EVENTTYPE_CREATE = 1
+EVENTTYPE_UPDATE = 2
+EVENTTYPE_REMOVE = 3
+DEVICEDRIVER_UNDEFINED = 0
+DEVICEDRIVER_OPENCONFIG = 1
+DEVICEDRIVER_TRANSPORT_API = 2
+DEVICEDRIVER_P4 = 3
+DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4
+DEVICEDRIVER_ONF_TR_352 = 5
+DEVICEOPERATIONALSTATUS_UNDEFINED = 0
+DEVICEOPERATIONALSTATUS_DISABLED = 1
+DEVICEOPERATIONALSTATUS_ENABLED = 2
+SERVICETYPE_UNKNOWN = 0
+SERVICETYPE_L3NM = 1
+SERVICETYPE_L2NM = 2
+SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3
+SERVICESTATUS_UNDEFINED = 0
+SERVICESTATUS_PLANNED = 1
+SERVICESTATUS_ACTIVE = 2
+SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
+CONFIGACTION_UNDEFINED = 0
+CONFIGACTION_SET = 1
+CONFIGACTION_DELETE = 2
+
+
+
+_EMPTY = _descriptor.Descriptor(
+  name='Empty',
+  full_name='context.Empty',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=50,
+  serialized_end=57,
+)
+
+
+_UUID = _descriptor.Descriptor(
+  name='Uuid',
+  full_name='context.Uuid',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='uuid', full_name='context.Uuid.uuid', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=59,
+  serialized_end=79,
+)
+
+
+_EVENT = _descriptor.Descriptor(
+  name='Event',
+  full_name='context.Event',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='context.Event.timestamp', index=0,
+      number=1, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='event_type', full_name='context.Event.event_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=81,
+  serialized_end=151,
+)
+
+
+_CONTEXTID = _descriptor.Descriptor(
+  name='ContextId',
+  full_name='context.ContextId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_uuid', full_name='context.ContextId.context_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=153,
+  serialized_end=201,
+)
+
+
+_CONTEXT = _descriptor.Descriptor(
+  name='Context',
+  full_name='context.Context',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.Context.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.Context.topology_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.Context.service_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='controller', full_name='context.Context.controller', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=204,
+  serialized_end=386,
+)
+
+
+_CONTEXTIDLIST = _descriptor.Descriptor(
+  name='ContextIdList',
+  full_name='context.ContextIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_ids', full_name='context.ContextIdList.context_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=388,
+  serialized_end=444,
+)
+
+
+_CONTEXTLIST = _descriptor.Descriptor(
+  name='ContextList',
+  full_name='context.ContextList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contexts', full_name='context.ContextList.contexts', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=446,
+  serialized_end=495,
+)
+
+
+_CONTEXTEVENT = _descriptor.Descriptor(
+  name='ContextEvent',
+  full_name='context.ContextEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ContextEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ContextEvent.context_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=497,
+  serialized_end=582,
+)
+
+
+_TOPOLOGYID = _descriptor.Descriptor(
+  name='TopologyId',
+  full_name='context.TopologyId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TopologyId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_uuid', full_name='context.TopologyId.topology_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=584,
+  serialized_end=674,
+)
+
+
+_TOPOLOGY = _descriptor.Descriptor(
+  name='Topology',
+  full_name='context.Topology',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.Topology.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.Topology.device_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.Topology.link_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=676,
+  serialized_end=802,
+)
+
+
+_TOPOLOGYIDLIST = _descriptor.Descriptor(
+  name='TopologyIdList',
+  full_name='context.TopologyIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.TopologyIdList.topology_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=804,
+  serialized_end=863,
+)
+
+
+_TOPOLOGYLIST = _descriptor.Descriptor(
+  name='TopologyList',
+  full_name='context.TopologyList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topologies', full_name='context.TopologyList.topologies', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=865,
+  serialized_end=918,
+)
+
+
+_TOPOLOGYEVENT = _descriptor.Descriptor(
+  name='TopologyEvent',
+  full_name='context.TopologyEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.TopologyEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.TopologyEvent.topology_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=920,
+  serialized_end=1008,
+)
+
+
+_DEVICEID = _descriptor.Descriptor(
+  name='DeviceId',
+  full_name='context.DeviceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_uuid', full_name='context.DeviceId.device_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1010,
+  serialized_end=1056,
+)
+
+
+_DEVICE = _descriptor.Descriptor(
+  name='Device',
+  full_name='context.Device',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.Device.device_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_type', full_name='context.Device.device_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_config', full_name='context.Device.device_config', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_operational_status', full_name='context.Device.device_operational_status', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_drivers', full_name='context.Device.device_drivers', index=4,
+      number=5, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_endpoints', full_name='context.Device.device_endpoints', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1059,
+  serialized_end=1341,
+)
+
+
+_DEVICECONFIG = _descriptor.Descriptor(
+  name='DeviceConfig',
+  full_name='context.DeviceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.DeviceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1343,
+  serialized_end=1400,
+)
+
+
+_DEVICEIDLIST = _descriptor.Descriptor(
+  name='DeviceIdList',
+  full_name='context.DeviceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.DeviceIdList.device_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1402,
+  serialized_end=1455,
+)
+
+
+_DEVICELIST = _descriptor.Descriptor(
+  name='DeviceList',
+  full_name='context.DeviceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='devices', full_name='context.DeviceList.devices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1457,
+  serialized_end=1503,
+)
+
+
+_DEVICEEVENT = _descriptor.Descriptor(
+  name='DeviceEvent',
+  full_name='context.DeviceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.DeviceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.DeviceEvent.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1505,
+  serialized_end=1587,
+)
+
+
+_LINKID = _descriptor.Descriptor(
+  name='LinkId',
+  full_name='context.LinkId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_uuid', full_name='context.LinkId.link_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1589,
+  serialized_end=1631,
+)
+
+
+_LINK = _descriptor.Descriptor(
+  name='Link',
+  full_name='context.Link',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.Link.link_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_endpoint_ids', full_name='context.Link.link_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1633,
+  serialized_end=1721,
+)
+
+
+_LINKIDLIST = _descriptor.Descriptor(
+  name='LinkIdList',
+  full_name='context.LinkIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.LinkIdList.link_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1723,
+  serialized_end=1770,
+)
+
+
+_LINKLIST = _descriptor.Descriptor(
+  name='LinkList',
+  full_name='context.LinkList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='links', full_name='context.LinkList.links', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1772,
+  serialized_end=1812,
+)
+
+
+_LINKEVENT = _descriptor.Descriptor(
+  name='LinkEvent',
+  full_name='context.LinkEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.LinkEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.LinkEvent.link_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1814,
+  serialized_end=1890,
+)
+
+
+_SERVICEID = _descriptor.Descriptor(
+  name='ServiceId',
+  full_name='context.ServiceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ServiceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_uuid', full_name='context.ServiceId.service_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1892,
+  serialized_end=1980,
+)
+
+
+_SERVICE = _descriptor.Descriptor(
+  name='Service',
+  full_name='context.Service',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Service.service_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_type', full_name='context.Service.service_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_endpoint_ids', full_name='context.Service.service_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_constraints', full_name='context.Service.service_constraints', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.Service.service_status', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_config', full_name='context.Service.service_config', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1983,
+  serialized_end=2277,
+)
+
+
+_SERVICESTATUS = _descriptor.Descriptor(
+  name='ServiceStatus',
+  full_name='context.ServiceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.ServiceStatus.service_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2279,
+  serialized_end=2346,
+)
+
+
+_SERVICECONFIG = _descriptor.Descriptor(
+  name='ServiceConfig',
+  full_name='context.ServiceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.ServiceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2348,
+  serialized_end=2406,
+)
+
+
+_SERVICEIDLIST = _descriptor.Descriptor(
+  name='ServiceIdList',
+  full_name='context.ServiceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.ServiceIdList.service_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2408,
+  serialized_end=2464,
+)
+
+
+_SERVICELIST = _descriptor.Descriptor(
+  name='ServiceList',
+  full_name='context.ServiceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='services', full_name='context.ServiceList.services', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2466,
+  serialized_end=2515,
+)
+
+
+_SERVICEEVENT = _descriptor.Descriptor(
+  name='ServiceEvent',
+  full_name='context.ServiceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ServiceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.ServiceEvent.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2517,
+  serialized_end=2602,
+)
+
+
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
+_CONNECTIONID = _descriptor.Descriptor(
+  name='ConnectionId',
+  full_name='context.ConnectionId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_uuid', full_name='context.ConnectionId.connection_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3211,
+  serialized_end=3265,
+)
+
+
+_CONNECTION = _descriptor.Descriptor(
+  name='Connection',
+  full_name='context.Connection',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.Connection.connection_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Connection.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='path_hops_endpoint_ids', full_name='context.Connection.path_hops_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='sub_service_ids', full_name='context.Connection.sub_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3268,
+  serialized_end=3464,
+)
+
+
+_CONNECTIONIDLIST = _descriptor.Descriptor(
+  name='ConnectionIdList',
+  full_name='context.ConnectionIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_ids', full_name='context.ConnectionIdList.connection_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3466,
+  serialized_end=3531,
+)
+
+
+_CONNECTIONLIST = _descriptor.Descriptor(
+  name='ConnectionList',
+  full_name='context.ConnectionList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connections', full_name='context.ConnectionList.connections', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3533,
+  serialized_end=3591,
+)
+
+
+_CONNECTIONEVENT = _descriptor.Descriptor(
+  name='ConnectionEvent',
+  full_name='context.ConnectionEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ConnectionEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.ConnectionEvent.connection_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3593,
+  serialized_end=3687,
+)
+
+
+_ENDPOINTID = _descriptor.Descriptor(
+  name='EndPointId',
+  full_name='context.EndPointId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.EndPointId.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.EndPointId.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_uuid', full_name='context.EndPointId.endpoint_uuid', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3690,
+  serialized_end=3820,
+)
+
+
+_ENDPOINT = _descriptor.Descriptor(
+  name='EndPoint',
+  full_name='context.EndPoint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='endpoint_id', full_name='context.EndPoint.endpoint_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_type', full_name='context.EndPoint.endpoint_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='kpi_sample_types', full_name='context.EndPoint.kpi_sample_types', index=2,
+      number=3, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3823,
+  serialized_end=3957,
+)
+
+
+_CONFIGRULE = _descriptor.Descriptor(
+  name='ConfigRule',
+  full_name='context.ConfigRule',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='action', full_name='context.ConfigRule.action', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_key', full_name='context.ConfigRule.resource_key', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_value', full_name='context.ConfigRule.resource_value', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3959,
+  serialized_end=4060,
+)
+
+
+_CONSTRAINT = _descriptor.Descriptor(
+  name='Constraint',
+  full_name='context.Constraint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='constraint_type', full_name='context.Constraint.constraint_type', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='constraint_value', full_name='context.Constraint.constraint_value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4062,
+  serialized_end=4125,
+)
+
+
+_TERAFLOWCONTROLLER = _descriptor.Descriptor(
+  name='TeraFlowController',
+  full_name='context.TeraFlowController',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TeraFlowController.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='ip_address', full_name='context.TeraFlowController.ip_address', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='port', full_name='context.TeraFlowController.port', index=2,
+      number=3, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4127,
+  serialized_end=4221,
+)
+
+
+_AUTHENTICATIONRESULT = _descriptor.Descriptor(
+  name='AuthenticationResult',
+  full_name='context.AuthenticationResult',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.AuthenticationResult.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='authenticated', full_name='context.AuthenticationResult.authenticated', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4223,
+  serialized_end=4308,
+)
+
+_EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
+_CONTEXTID.fields_by_name['context_uuid'].message_type = _UUID
+_CONTEXT.fields_by_name['context_id'].message_type = _CONTEXTID
+_CONTEXT.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_CONTEXT.fields_by_name['service_ids'].message_type = _SERVICEID
+_CONTEXT.fields_by_name['controller'].message_type = _TERAFLOWCONTROLLER
+_CONTEXTIDLIST.fields_by_name['context_ids'].message_type = _CONTEXTID
+_CONTEXTLIST.fields_by_name['contexts'].message_type = _CONTEXT
+_CONTEXTEVENT.fields_by_name['event'].message_type = _EVENT
+_CONTEXTEVENT.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['topology_uuid'].message_type = _UUID
+_TOPOLOGY.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_TOPOLOGY.fields_by_name['device_ids'].message_type = _DEVICEID
+_TOPOLOGY.fields_by_name['link_ids'].message_type = _LINKID
+_TOPOLOGYIDLIST.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_TOPOLOGYLIST.fields_by_name['topologies'].message_type = _TOPOLOGY
+_TOPOLOGYEVENT.fields_by_name['event'].message_type = _EVENT
+_TOPOLOGYEVENT.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_DEVICEID.fields_by_name['device_uuid'].message_type = _UUID
+_DEVICE.fields_by_name['device_id'].message_type = _DEVICEID
+_DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG
+_DEVICE.fields_by_name['device_operational_status'].enum_type = _DEVICEOPERATIONALSTATUSENUM
+_DEVICE.fields_by_name['device_drivers'].enum_type = _DEVICEDRIVERENUM
+_DEVICE.fields_by_name['device_endpoints'].message_type = _ENDPOINT
+_DEVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_DEVICEIDLIST.fields_by_name['device_ids'].message_type = _DEVICEID
+_DEVICELIST.fields_by_name['devices'].message_type = _DEVICE
+_DEVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_DEVICEEVENT.fields_by_name['device_id'].message_type = _DEVICEID
+_LINKID.fields_by_name['link_uuid'].message_type = _UUID
+_LINK.fields_by_name['link_id'].message_type = _LINKID
+_LINK.fields_by_name['link_endpoint_ids'].message_type = _ENDPOINTID
+_LINKIDLIST.fields_by_name['link_ids'].message_type = _LINKID
+_LINKLIST.fields_by_name['links'].message_type = _LINK
+_LINKEVENT.fields_by_name['event'].message_type = _EVENT
+_LINKEVENT.fields_by_name['link_id'].message_type = _LINKID
+_SERVICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SERVICEID.fields_by_name['service_uuid'].message_type = _UUID
+_SERVICE.fields_by_name['service_id'].message_type = _SERVICEID
+_SERVICE.fields_by_name['service_type'].enum_type = _SERVICETYPEENUM
+_SERVICE.fields_by_name['service_endpoint_ids'].message_type = _ENDPOINTID
+_SERVICE.fields_by_name['service_constraints'].message_type = _CONSTRAINT
+_SERVICE.fields_by_name['service_status'].message_type = _SERVICESTATUS
+_SERVICE.fields_by_name['service_config'].message_type = _SERVICECONFIG
+_SERVICESTATUS.fields_by_name['service_status'].enum_type = _SERVICESTATUSENUM
+_SERVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
+_SERVICELIST.fields_by_name['services'].message_type = _SERVICE
+_SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
+_CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
+_CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
+_CONNECTION.fields_by_name['path_hops_endpoint_ids'].message_type = _ENDPOINTID
+_CONNECTION.fields_by_name['sub_service_ids'].message_type = _SERVICEID
+_CONNECTIONIDLIST.fields_by_name['connection_ids'].message_type = _CONNECTIONID
+_CONNECTIONLIST.fields_by_name['connections'].message_type = _CONNECTION
+_CONNECTIONEVENT.fields_by_name['event'].message_type = _EVENT
+_CONNECTIONEVENT.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_ENDPOINTID.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID
+_ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID
+_ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID
+_ENDPOINT.fields_by_name['kpi_sample_types'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE
+_CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM
+_TERAFLOWCONTROLLER.fields_by_name['context_id'].message_type = _CONTEXTID
+_AUTHENTICATIONRESULT.fields_by_name['context_id'].message_type = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
+DESCRIPTOR.message_types_by_name['Uuid'] = _UUID
+DESCRIPTOR.message_types_by_name['Event'] = _EVENT
+DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT
+DESCRIPTOR.message_types_by_name['ContextIdList'] = _CONTEXTIDLIST
+DESCRIPTOR.message_types_by_name['ContextList'] = _CONTEXTLIST
+DESCRIPTOR.message_types_by_name['ContextEvent'] = _CONTEXTEVENT
+DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID
+DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY
+DESCRIPTOR.message_types_by_name['TopologyIdList'] = _TOPOLOGYIDLIST
+DESCRIPTOR.message_types_by_name['TopologyList'] = _TOPOLOGYLIST
+DESCRIPTOR.message_types_by_name['TopologyEvent'] = _TOPOLOGYEVENT
+DESCRIPTOR.message_types_by_name['DeviceId'] = _DEVICEID
+DESCRIPTOR.message_types_by_name['Device'] = _DEVICE
+DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG
+DESCRIPTOR.message_types_by_name['DeviceIdList'] = _DEVICEIDLIST
+DESCRIPTOR.message_types_by_name['DeviceList'] = _DEVICELIST
+DESCRIPTOR.message_types_by_name['DeviceEvent'] = _DEVICEEVENT
+DESCRIPTOR.message_types_by_name['LinkId'] = _LINKID
+DESCRIPTOR.message_types_by_name['Link'] = _LINK
+DESCRIPTOR.message_types_by_name['LinkIdList'] = _LINKIDLIST
+DESCRIPTOR.message_types_by_name['LinkList'] = _LINKLIST
+DESCRIPTOR.message_types_by_name['LinkEvent'] = _LINKEVENT
+DESCRIPTOR.message_types_by_name['ServiceId'] = _SERVICEID
+DESCRIPTOR.message_types_by_name['Service'] = _SERVICE
+DESCRIPTOR.message_types_by_name['ServiceStatus'] = _SERVICESTATUS
+DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
+DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
+DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
+DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
+DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
+DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
+DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
+DESCRIPTOR.message_types_by_name['ConnectionList'] = _CONNECTIONLIST
+DESCRIPTOR.message_types_by_name['ConnectionEvent'] = _CONNECTIONEVENT
+DESCRIPTOR.message_types_by_name['EndPointId'] = _ENDPOINTID
+DESCRIPTOR.message_types_by_name['EndPoint'] = _ENDPOINT
+DESCRIPTOR.message_types_by_name['ConfigRule'] = _CONFIGRULE
+DESCRIPTOR.message_types_by_name['Constraint'] = _CONSTRAINT
+DESCRIPTOR.message_types_by_name['TeraFlowController'] = _TERAFLOWCONTROLLER
+DESCRIPTOR.message_types_by_name['AuthenticationResult'] = _AUTHENTICATIONRESULT
+DESCRIPTOR.enum_types_by_name['EventTypeEnum'] = _EVENTTYPEENUM
+DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
+DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
+DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
+DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
+  'DESCRIPTOR' : _EMPTY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Empty)
+  })
+_sym_db.RegisterMessage(Empty)
+
+Uuid = _reflection.GeneratedProtocolMessageType('Uuid', (_message.Message,), {
+  'DESCRIPTOR' : _UUID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Uuid)
+  })
+_sym_db.RegisterMessage(Uuid)
+
+Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), {
+  'DESCRIPTOR' : _EVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Event)
+  })
+_sym_db.RegisterMessage(Event)
+
+ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextId)
+  })
+_sym_db.RegisterMessage(ContextId)
+
+Context = _reflection.GeneratedProtocolMessageType('Context', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Context)
+  })
+_sym_db.RegisterMessage(Context)
+
+ContextIdList = _reflection.GeneratedProtocolMessageType('ContextIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextIdList)
+  })
+_sym_db.RegisterMessage(ContextIdList)
+
+ContextList = _reflection.GeneratedProtocolMessageType('ContextList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextList)
+  })
+_sym_db.RegisterMessage(ContextList)
+
+ContextEvent = _reflection.GeneratedProtocolMessageType('ContextEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextEvent)
+  })
+_sym_db.RegisterMessage(ContextEvent)
+
+TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyId)
+  })
+_sym_db.RegisterMessage(TopologyId)
+
+Topology = _reflection.GeneratedProtocolMessageType('Topology', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Topology)
+  })
+_sym_db.RegisterMessage(Topology)
+
+TopologyIdList = _reflection.GeneratedProtocolMessageType('TopologyIdList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyIdList)
+  })
+_sym_db.RegisterMessage(TopologyIdList)
+
+TopologyList = _reflection.GeneratedProtocolMessageType('TopologyList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyList)
+  })
+_sym_db.RegisterMessage(TopologyList)
+
+TopologyEvent = _reflection.GeneratedProtocolMessageType('TopologyEvent', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyEvent)
+  })
+_sym_db.RegisterMessage(TopologyEvent)
+
+DeviceId = _reflection.GeneratedProtocolMessageType('DeviceId', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceId)
+  })
+_sym_db.RegisterMessage(DeviceId)
+
+Device = _reflection.GeneratedProtocolMessageType('Device', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Device)
+  })
+_sym_db.RegisterMessage(Device)
+
+DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceConfig)
+  })
+_sym_db.RegisterMessage(DeviceConfig)
+
+DeviceIdList = _reflection.GeneratedProtocolMessageType('DeviceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceIdList)
+  })
+_sym_db.RegisterMessage(DeviceIdList)
+
+DeviceList = _reflection.GeneratedProtocolMessageType('DeviceList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceList)
+  })
+_sym_db.RegisterMessage(DeviceList)
+
+DeviceEvent = _reflection.GeneratedProtocolMessageType('DeviceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceEvent)
+  })
+_sym_db.RegisterMessage(DeviceEvent)
+
+LinkId = _reflection.GeneratedProtocolMessageType('LinkId', (_message.Message,), {
+  'DESCRIPTOR' : _LINKID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkId)
+  })
+_sym_db.RegisterMessage(LinkId)
+
+Link = _reflection.GeneratedProtocolMessageType('Link', (_message.Message,), {
+  'DESCRIPTOR' : _LINK,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Link)
+  })
+_sym_db.RegisterMessage(Link)
+
+LinkIdList = _reflection.GeneratedProtocolMessageType('LinkIdList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkIdList)
+  })
+_sym_db.RegisterMessage(LinkIdList)
+
+LinkList = _reflection.GeneratedProtocolMessageType('LinkList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkList)
+  })
+_sym_db.RegisterMessage(LinkList)
+
+LinkEvent = _reflection.GeneratedProtocolMessageType('LinkEvent', (_message.Message,), {
+  'DESCRIPTOR' : _LINKEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkEvent)
+  })
+_sym_db.RegisterMessage(LinkEvent)
+
+ServiceId = _reflection.GeneratedProtocolMessageType('ServiceId', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceId)
+  })
+_sym_db.RegisterMessage(ServiceId)
+
+Service = _reflection.GeneratedProtocolMessageType('Service', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Service)
+  })
+_sym_db.RegisterMessage(Service)
+
+ServiceStatus = _reflection.GeneratedProtocolMessageType('ServiceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceStatus)
+  })
+_sym_db.RegisterMessage(ServiceStatus)
+
+ServiceConfig = _reflection.GeneratedProtocolMessageType('ServiceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceConfig)
+  })
+_sym_db.RegisterMessage(ServiceConfig)
+
+ServiceIdList = _reflection.GeneratedProtocolMessageType('ServiceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceIdList)
+  })
+_sym_db.RegisterMessage(ServiceIdList)
+
+ServiceList = _reflection.GeneratedProtocolMessageType('ServiceList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceList)
+  })
+_sym_db.RegisterMessage(ServiceList)
+
+ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceEvent)
+  })
+_sym_db.RegisterMessage(ServiceEvent)
+
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
+ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionId)
+  })
+_sym_db.RegisterMessage(ConnectionId)
+
+Connection = _reflection.GeneratedProtocolMessageType('Connection', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTION,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Connection)
+  })
+_sym_db.RegisterMessage(Connection)
+
+ConnectionIdList = _reflection.GeneratedProtocolMessageType('ConnectionIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionIdList)
+  })
+_sym_db.RegisterMessage(ConnectionIdList)
+
+ConnectionList = _reflection.GeneratedProtocolMessageType('ConnectionList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionList)
+  })
+_sym_db.RegisterMessage(ConnectionList)
+
+ConnectionEvent = _reflection.GeneratedProtocolMessageType('ConnectionEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionEvent)
+  })
+_sym_db.RegisterMessage(ConnectionEvent)
+
+EndPointId = _reflection.GeneratedProtocolMessageType('EndPointId', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPointId)
+  })
+_sym_db.RegisterMessage(EndPointId)
+
+EndPoint = _reflection.GeneratedProtocolMessageType('EndPoint', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPoint)
+  })
+_sym_db.RegisterMessage(EndPoint)
+
+ConfigRule = _reflection.GeneratedProtocolMessageType('ConfigRule', (_message.Message,), {
+  'DESCRIPTOR' : _CONFIGRULE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConfigRule)
+  })
+_sym_db.RegisterMessage(ConfigRule)
+
+Constraint = _reflection.GeneratedProtocolMessageType('Constraint', (_message.Message,), {
+  'DESCRIPTOR' : _CONSTRAINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Constraint)
+  })
+_sym_db.RegisterMessage(Constraint)
+
+TeraFlowController = _reflection.GeneratedProtocolMessageType('TeraFlowController', (_message.Message,), {
+  'DESCRIPTOR' : _TERAFLOWCONTROLLER,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TeraFlowController)
+  })
+_sym_db.RegisterMessage(TeraFlowController)
+
+AuthenticationResult = _reflection.GeneratedProtocolMessageType('AuthenticationResult', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHENTICATIONRESULT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.AuthenticationResult)
+  })
+_sym_db.RegisterMessage(AuthenticationResult)
+
+
+
+_CONTEXTSERVICE = _descriptor.ServiceDescriptor(
+  name='ContextService',
+  full_name='context.ContextService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=5273,
+  serialized_end=7688,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='ListContextIds',
+    full_name='context.ContextService.ListContextIds',
+    index=0,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListContexts',
+    full_name='context.ContextService.ListContexts',
+    index=1,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContext',
+    full_name='context.ContextService.GetContext',
+    index=2,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_CONTEXT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetContext',
+    full_name='context.ContextService.SetContext',
+    index=3,
+    containing_service=None,
+    input_type=_CONTEXT,
+    output_type=_CONTEXTID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveContext',
+    full_name='context.ContextService.RemoveContext',
+    index=4,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContextEvents',
+    full_name='context.ContextService.GetContextEvents',
+    index=5,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologyIds',
+    full_name='context.ContextService.ListTopologyIds',
+    index=6,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologies',
+    full_name='context.ContextService.ListTopologies',
+    index=7,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopology',
+    full_name='context.ContextService.GetTopology',
+    index=8,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_TOPOLOGY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetTopology',
+    full_name='context.ContextService.SetTopology',
+    index=9,
+    containing_service=None,
+    input_type=_TOPOLOGY,
+    output_type=_TOPOLOGYID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveTopology',
+    full_name='context.ContextService.RemoveTopology',
+    index=10,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopologyEvents',
+    full_name='context.ContextService.GetTopologyEvents',
+    index=11,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_TOPOLOGYEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDeviceIds',
+    full_name='context.ContextService.ListDeviceIds',
+    index=12,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDevices',
+    full_name='context.ContextService.ListDevices',
+    index=13,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDevice',
+    full_name='context.ContextService.GetDevice',
+    index=14,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_DEVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetDevice',
+    full_name='context.ContextService.SetDevice',
+    index=15,
+    containing_service=None,
+    input_type=_DEVICE,
+    output_type=_DEVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveDevice',
+    full_name='context.ContextService.RemoveDevice',
+    index=16,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDeviceEvents',
+    full_name='context.ContextService.GetDeviceEvents',
+    index=17,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinkIds',
+    full_name='context.ContextService.ListLinkIds',
+    index=18,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinks',
+    full_name='context.ContextService.ListLinks',
+    index=19,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLink',
+    full_name='context.ContextService.GetLink',
+    index=20,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_LINK,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetLink',
+    full_name='context.ContextService.SetLink',
+    index=21,
+    containing_service=None,
+    input_type=_LINK,
+    output_type=_LINKID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveLink',
+    full_name='context.ContextService.RemoveLink',
+    index=22,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLinkEvents',
+    full_name='context.ContextService.GetLinkEvents',
+    index=23,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServiceIds',
+    full_name='context.ContextService.ListServiceIds',
+    index=24,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServices',
+    full_name='context.ContextService.ListServices',
+    index=25,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetService',
+    full_name='context.ContextService.GetService',
+    index=26,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_SERVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetService',
+    full_name='context.ContextService.SetService',
+    index=27,
+    containing_service=None,
+    input_type=_SERVICE,
+    output_type=_SERVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveService',
+    full_name='context.ContextService.RemoveService',
+    index=28,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetServiceEvents',
+    full_name='context.ContextService.GetServiceEvents',
+    index=29,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SERVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnectionIds',
+    full_name='context.ContextService.ListConnectionIds',
+    index=36,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnections',
+    full_name='context.ContextService.ListConnections',
+    index=37,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnection',
+    full_name='context.ContextService.GetConnection',
+    index=38,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_CONNECTION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetConnection',
+    full_name='context.ContextService.SetConnection',
+    index=39,
+    containing_service=None,
+    input_type=_CONNECTION,
+    output_type=_CONNECTIONID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveConnection',
+    full_name='context.ContextService.RemoveConnection',
+    index=40,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnectionEvents',
+    full_name='context.ContextService.GetConnectionEvents',
+    index=41,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONNECTIONEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CONTEXTSERVICE)
+
+DESCRIPTOR.services_by_name['ContextService'] = _CONTEXTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/l3_centralizedattackdetector/proto/kpi_sample_types_pb2.py b/src/l3_centralizedattackdetector/proto/kpi_sample_types_pb2.py
new file mode 100644
index 000000000..ea7fd2f82
--- /dev/null
+++ b/src/l3_centralizedattackdetector/proto/kpi_sample_types_pb2.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: kpi_sample_types.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='kpi_sample_types.proto',
+  package='kpi_sample_types',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*\xbe\x01\n\rKpiSampleType\x12\x19\n\x15KPISAMPLETYPE_UNKNOWN\x10\x00\x12%\n!KPISAMPLETYPE_PACKETS_TRANSMITTED\x10\x65\x12\"\n\x1eKPISAMPLETYPE_PACKETS_RECEIVED\x10\x66\x12$\n\x1fKPISAMPLETYPE_BYTES_TRANSMITTED\x10\xc9\x01\x12!\n\x1cKPISAMPLETYPE_BYTES_RECEIVED\x10\xca\x01\x62\x06proto3'
+)
+
+_KPISAMPLETYPE = _descriptor.EnumDescriptor(
+  name='KpiSampleType',
+  full_name='kpi_sample_types.KpiSampleType',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_TRANSMITTED', index=1, number=101,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_RECEIVED', index=2, number=102,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_TRANSMITTED', index=3, number=201,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_RECEIVED', index=4, number=202,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=45,
+  serialized_end=235,
+)
+_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE)
+
+KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE)
+KPISAMPLETYPE_UNKNOWN = 0
+KPISAMPLETYPE_PACKETS_TRANSMITTED = 101
+KPISAMPLETYPE_PACKETS_RECEIVED = 102
+KPISAMPLETYPE_BYTES_TRANSMITTED = 201
+KPISAMPLETYPE_BYTES_RECEIVED = 202
+
+
+DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/l3_centralizedattackdetector/proto/l3_attackmitigator_pb2.py b/src/l3_centralizedattackdetector/proto/l3_attackmitigator_pb2.py
index 0ad49c2ed..e148d0a2c 100644
--- a/src/l3_centralizedattackdetector/proto/l3_attackmitigator_pb2.py
+++ b/src/l3_centralizedattackdetector/proto/l3_attackmitigator_pb2.py
@@ -11,6 +11,7 @@ from google.protobuf import symbol_database as _symbol_database
 _sym_db = _symbol_database.Default()
 
 
+from . import context_pb2 as context__pb2
 
 
 DESCRIPTOR = _descriptor.FileDescriptor(
@@ -19,129 +20,93 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\x18l3_attackmitigator.proto\"2\n\x0e\x45mptyMitigator\x12\x14\n\x07message\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_message\"\xf9\x01\n\x06Output\x12\x12\n\nconfidence\x18\x01 \x01(\x02\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x0c\n\x04ip_o\x18\x03 \x01(\t\x12\x10\n\x08tag_name\x18\x04 \x01(\t\x12\x0b\n\x03tag\x18\x05 \x01(\x05\x12\x0f\n\x07\x66low_id\x18\x06 \x01(\t\x12\x10\n\x08protocol\x18\x07 \x01(\t\x12\x0e\n\x06port_d\x18\x08 \x01(\t\x12\x12\n\x05ml_id\x18\t \x01(\tH\x00\x88\x01\x01\x12\x17\n\ntime_start\x18\n \x01(\x02H\x01\x88\x01\x01\x12\x15\n\x08time_end\x18\x0b \x01(\x02H\x02\x88\x01\x01\x42\x08\n\x06_ml_idB\r\n\x0b_time_startB\x0b\n\t_time_end2r\n\x11L3Attackmitigator\x12(\n\nSendOutput\x12\x07.Output\x1a\x0f.EmptyMitigator\"\x00\x12\x33\n\rGetMitigation\x12\x0f.EmptyMitigator\x1a\x0f.EmptyMitigator\"\x00\x62\x06proto3'
-)
+  serialized_pb=b'\n\x18l3_attackmitigator.proto\x1a\rcontext.proto\"\xd5\x01\n\x17L3AttackmitigatorOutput\x12\x12\n\nconfidence\x18\x01 \x01(\x02\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x0c\n\x04ip_o\x18\x03 \x01(\t\x12\x10\n\x08tag_name\x18\x04 \x01(\t\x12\x0b\n\x03tag\x18\x05 \x01(\x05\x12\x0f\n\x07\x66low_id\x18\x06 \x01(\t\x12\x10\n\x08protocol\x18\x07 \x01(\t\x12\x0e\n\x06port_d\x18\x08 \x01(\t\x12\r\n\x05ml_id\x18\t \x01(\t\x12\x12\n\ntime_start\x18\n \x01(\x02\x12\x10\n\x08time_end\x18\x0b \x01(\x02\x32\x80\x01\n\x11L3Attackmitigator\x12\x38\n\nSendOutput\x12\x18.L3AttackmitigatorOutput\x1a\x0e.context.Empty\"\x00\x12\x31\n\rGetMitigation\x12\x0e.context.Empty\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
+  ,
+  dependencies=[context__pb2.DESCRIPTOR,])
 
 
 
 
-_EMPTYMITIGATOR = _descriptor.Descriptor(
-  name='EmptyMitigator',
-  full_name='EmptyMitigator',
+_L3ATTACKMITIGATOROUTPUT = _descriptor.Descriptor(
+  name='L3AttackmitigatorOutput',
+  full_name='L3AttackmitigatorOutput',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='message', full_name='EmptyMitigator.message', index=0,
-      number=1, type=9, cpp_type=9, label=1,
-      has_default_value=False, default_value=b"".decode('utf-8'),
-      message_type=None, enum_type=None, containing_type=None,
-      is_extension=False, extension_scope=None,
-      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
-  ],
-  extensions=[
-  ],
-  nested_types=[],
-  enum_types=[
-  ],
-  serialized_options=None,
-  is_extendable=False,
-  syntax='proto3',
-  extension_ranges=[],
-  oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_message', full_name='EmptyMitigator._message',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-  ],
-  serialized_start=28,
-  serialized_end=78,
-)
-
-
-_OUTPUT = _descriptor.Descriptor(
-  name='Output',
-  full_name='Output',
-  filename=None,
-  file=DESCRIPTOR,
-  containing_type=None,
-  create_key=_descriptor._internal_create_key,
-  fields=[
-    _descriptor.FieldDescriptor(
-      name='confidence', full_name='Output.confidence', index=0,
+      name='confidence', full_name='L3AttackmitigatorOutput.confidence', index=0,
       number=1, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='timestamp', full_name='Output.timestamp', index=1,
+      name='timestamp', full_name='L3AttackmitigatorOutput.timestamp', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ip_o', full_name='Output.ip_o', index=2,
+      name='ip_o', full_name='L3AttackmitigatorOutput.ip_o', index=2,
       number=3, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='tag_name', full_name='Output.tag_name', index=3,
+      name='tag_name', full_name='L3AttackmitigatorOutput.tag_name', index=3,
       number=4, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='tag', full_name='Output.tag', index=4,
+      name='tag', full_name='L3AttackmitigatorOutput.tag', index=4,
       number=5, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='flow_id', full_name='Output.flow_id', index=5,
+      name='flow_id', full_name='L3AttackmitigatorOutput.flow_id', index=5,
       number=6, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='protocol', full_name='Output.protocol', index=6,
+      name='protocol', full_name='L3AttackmitigatorOutput.protocol', index=6,
       number=7, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='port_d', full_name='Output.port_d', index=7,
+      name='port_d', full_name='L3AttackmitigatorOutput.port_d', index=7,
       number=8, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ml_id', full_name='Output.ml_id', index=8,
+      name='ml_id', full_name='L3AttackmitigatorOutput.ml_id', index=8,
       number=9, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_start', full_name='Output.time_start', index=9,
+      name='time_start', full_name='L3AttackmitigatorOutput.time_start', index=9,
       number=10, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_end', full_name='Output.time_end', index=10,
+      name='time_end', full_name='L3AttackmitigatorOutput.time_end', index=10,
       number=11, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
@@ -158,55 +123,20 @@ _OUTPUT = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_ml_id', full_name='Output._ml_id',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_start', full_name='Output._time_start',
-      index=1, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_end', full_name='Output._time_end',
-      index=2, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
   ],
-  serialized_start=81,
-  serialized_end=330,
+  serialized_start=44,
+  serialized_end=257,
 )
 
-_EMPTYMITIGATOR.oneofs_by_name['_message'].fields.append(
-  _EMPTYMITIGATOR.fields_by_name['message'])
-_EMPTYMITIGATOR.fields_by_name['message'].containing_oneof = _EMPTYMITIGATOR.oneofs_by_name['_message']
-_OUTPUT.oneofs_by_name['_ml_id'].fields.append(
-  _OUTPUT.fields_by_name['ml_id'])
-_OUTPUT.fields_by_name['ml_id'].containing_oneof = _OUTPUT.oneofs_by_name['_ml_id']
-_OUTPUT.oneofs_by_name['_time_start'].fields.append(
-  _OUTPUT.fields_by_name['time_start'])
-_OUTPUT.fields_by_name['time_start'].containing_oneof = _OUTPUT.oneofs_by_name['_time_start']
-_OUTPUT.oneofs_by_name['_time_end'].fields.append(
-  _OUTPUT.fields_by_name['time_end'])
-_OUTPUT.fields_by_name['time_end'].containing_oneof = _OUTPUT.oneofs_by_name['_time_end']
-DESCRIPTOR.message_types_by_name['EmptyMitigator'] = _EMPTYMITIGATOR
-DESCRIPTOR.message_types_by_name['Output'] = _OUTPUT
+DESCRIPTOR.message_types_by_name['L3AttackmitigatorOutput'] = _L3ATTACKMITIGATOROUTPUT
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
-EmptyMitigator = _reflection.GeneratedProtocolMessageType('EmptyMitigator', (_message.Message,), {
-  'DESCRIPTOR' : _EMPTYMITIGATOR,
-  '__module__' : 'l3_attackmitigator_pb2'
-  # @@protoc_insertion_point(class_scope:EmptyMitigator)
-  })
-_sym_db.RegisterMessage(EmptyMitigator)
-
-Output = _reflection.GeneratedProtocolMessageType('Output', (_message.Message,), {
-  'DESCRIPTOR' : _OUTPUT,
+L3AttackmitigatorOutput = _reflection.GeneratedProtocolMessageType('L3AttackmitigatorOutput', (_message.Message,), {
+  'DESCRIPTOR' : _L3ATTACKMITIGATOROUTPUT,
   '__module__' : 'l3_attackmitigator_pb2'
-  # @@protoc_insertion_point(class_scope:Output)
+  # @@protoc_insertion_point(class_scope:L3AttackmitigatorOutput)
   })
-_sym_db.RegisterMessage(Output)
+_sym_db.RegisterMessage(L3AttackmitigatorOutput)
 
 
 
@@ -217,16 +147,16 @@ _L3ATTACKMITIGATOR = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=332,
-  serialized_end=446,
+  serialized_start=260,
+  serialized_end=388,
   methods=[
   _descriptor.MethodDescriptor(
     name='SendOutput',
     full_name='L3Attackmitigator.SendOutput',
     index=0,
     containing_service=None,
-    input_type=_OUTPUT,
-    output_type=_EMPTYMITIGATOR,
+    input_type=_L3ATTACKMITIGATOROUTPUT,
+    output_type=context__pb2._EMPTY,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
@@ -235,8 +165,8 @@ _L3ATTACKMITIGATOR = _descriptor.ServiceDescriptor(
     full_name='L3Attackmitigator.GetMitigation',
     index=1,
     containing_service=None,
-    input_type=_EMPTYMITIGATOR,
-    output_type=_EMPTYMITIGATOR,
+    input_type=context__pb2._EMPTY,
+    output_type=context__pb2._EMPTY,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
diff --git a/src/l3_centralizedattackdetector/proto/l3_attackmitigator_pb2_grpc.py b/src/l3_centralizedattackdetector/proto/l3_attackmitigator_pb2_grpc.py
deleted file mode 100644
index 3942d6843..000000000
--- a/src/l3_centralizedattackdetector/proto/l3_attackmitigator_pb2_grpc.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
-"""Client and server classes corresponding to protobuf-defined services."""
-import grpc
-
-
-from . import l3_attackmitigator_pb2 as l3__attackmitigator__pb2
-
-
-class L3AttackmitigatorStub(object):
-    """Missing associated documentation comment in .proto file."""
-
-    def __init__(self, channel):
-        """Constructor.
-
-        Args:
-            channel: A grpc.Channel.
-        """
-        self.SendOutput = channel.unary_unary(
-                '/L3Attackmitigator/SendOutput',
-                request_serializer=l3__attackmitigator__pb2.Output.SerializeToString,
-                response_deserializer=l3__attackmitigator__pb2.EmptyMitigator.FromString,
-                )
-        self.GetMitigation = channel.unary_unary(
-                '/L3Attackmitigator/GetMitigation',
-                request_serializer=l3__attackmitigator__pb2.EmptyMitigator.SerializeToString,
-                response_deserializer=l3__attackmitigator__pb2.EmptyMitigator.FromString,
-                )
-
-
-class L3AttackmitigatorServicer(object):
-    """Missing associated documentation comment in .proto file."""
-
-    def SendOutput(self, request, context):
-        """Sends a greeting
-        """
-        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-        context.set_details('Method not implemented!')
-        raise NotImplementedError('Method not implemented!')
-
-    def GetMitigation(self, request, context):
-        """Sends another greeting
-        """
-        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-        context.set_details('Method not implemented!')
-        raise NotImplementedError('Method not implemented!')
-
-
-def add_L3AttackmitigatorServicer_to_server(servicer, server):
-    rpc_method_handlers = {
-            'SendOutput': grpc.unary_unary_rpc_method_handler(
-                    servicer.SendOutput,
-                    request_deserializer=l3__attackmitigator__pb2.Output.FromString,
-                    response_serializer=l3__attackmitigator__pb2.EmptyMitigator.SerializeToString,
-            ),
-            'GetMitigation': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetMitigation,
-                    request_deserializer=l3__attackmitigator__pb2.EmptyMitigator.FromString,
-                    response_serializer=l3__attackmitigator__pb2.EmptyMitigator.SerializeToString,
-            ),
-    }
-    generic_handler = grpc.method_handlers_generic_handler(
-            'L3Attackmitigator', rpc_method_handlers)
-    server.add_generic_rpc_handlers((generic_handler,))
-
-
- # This class is part of an EXPERIMENTAL API.
-class L3Attackmitigator(object):
-    """Missing associated documentation comment in .proto file."""
-
-    @staticmethod
-    def SendOutput(request,
-            target,
-            options=(),
-            channel_credentials=None,
-            call_credentials=None,
-            insecure=False,
-            compression=None,
-            wait_for_ready=None,
-            timeout=None,
-            metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/L3Attackmitigator/SendOutput',
-            l3__attackmitigator__pb2.Output.SerializeToString,
-            l3__attackmitigator__pb2.EmptyMitigator.FromString,
-            options, channel_credentials,
-            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
-
-    @staticmethod
-    def GetMitigation(request,
-            target,
-            options=(),
-            channel_credentials=None,
-            call_credentials=None,
-            insecure=False,
-            compression=None,
-            wait_for_ready=None,
-            timeout=None,
-            metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/L3Attackmitigator/GetMitigation',
-            l3__attackmitigator__pb2.EmptyMitigator.SerializeToString,
-            l3__attackmitigator__pb2.EmptyMitigator.FromString,
-            options, channel_credentials,
-            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/l3_centralizedattackdetector/proto/l3_centralizedattackdetector_pb2.py b/src/l3_centralizedattackdetector/proto/l3_centralizedattackdetector_pb2.py
index cafbc6bf8..517fdb84b 100644
--- a/src/l3_centralizedattackdetector/proto/l3_centralizedattackdetector_pb2.py
+++ b/src/l3_centralizedattackdetector/proto/l3_centralizedattackdetector_pb2.py
@@ -19,127 +19,127 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\"l3_centralizedattackdetector.proto\"\xd9\x03\n\nModelInput\x12 \n\x18n_packets_server_seconds\x18\x01 \x01(\x02\x12 \n\x18n_packets_client_seconds\x18\x02 \x01(\x02\x12\x1d\n\x15n_bits_server_seconds\x18\x03 \x01(\x02\x12\x1d\n\x15n_bits_client_seconds\x18\x04 \x01(\x02\x12&\n\x1en_bits_server_n_packets_server\x18\x05 \x01(\x02\x12&\n\x1en_bits_client_n_packets_client\x18\x06 \x01(\x02\x12)\n!n_packets_server_n_packets_client\x18\x07 \x01(\x02\x12#\n\x1bn_bits_server_n_bits_client\x18\x08 \x01(\x02\x12\x0c\n\x04ip_o\x18\t \x01(\t\x12\x0e\n\x06port_o\x18\n \x01(\t\x12\x0c\n\x04ip_d\x18\x0b \x01(\t\x12\x0e\n\x06port_d\x18\x0c \x01(\t\x12\x0f\n\x07\x66low_id\x18\r \x01(\t\x12\x10\n\x08protocol\x18\x0e \x01(\t\x12\x17\n\ntime_start\x18\x0f \x01(\x02H\x00\x88\x01\x01\x12\x15\n\x08time_end\x18\x10 \x01(\x02H\x01\x88\x01\x01\x42\r\n\x0b_time_startB\x0b\n\t_time_end\")\n\x05\x45mpty\x12\x14\n\x07message\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_message\"\xfe\x01\n\x0bModelOutput\x12\x12\n\nconfidence\x18\x01 \x01(\x02\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x0c\n\x04ip_o\x18\x03 \x01(\t\x12\x10\n\x08tag_name\x18\x04 \x01(\t\x12\x0b\n\x03tag\x18\x05 \x01(\x05\x12\x0f\n\x07\x66low_id\x18\x06 \x01(\t\x12\x10\n\x08protocol\x18\x07 \x01(\t\x12\x0e\n\x06port_d\x18\x08 \x01(\t\x12\x12\n\x05ml_id\x18\t \x01(\tH\x00\x88\x01\x01\x12\x17\n\ntime_start\x18\n \x01(\x02H\x01\x88\x01\x01\x12\x15\n\x08time_end\x18\x0b \x01(\x02H\x02\x88\x01\x01\x42\x08\n\x06_ml_idB\r\n\x0b_time_startB\x0b\n\t_time_end2f\n\x1bL3Centralizedattackdetector\x12\"\n\tSendInput\x12\x0b.ModelInput\x1a\x06.Empty\"\x00\x12#\n\tGetOutput\x12\x06.Empty\x1a\x0c.ModelOutput\"\x00\x62\x06proto3'
+  serialized_pb=b'\n\"l3_centralizedattackdetector.proto\"\xcb\x03\n\"L3CentralizedattackdetectorMetrics\x12 \n\x18n_packets_server_seconds\x18\x01 \x01(\x02\x12 \n\x18n_packets_client_seconds\x18\x02 \x01(\x02\x12\x1d\n\x15n_bits_server_seconds\x18\x03 \x01(\x02\x12\x1d\n\x15n_bits_client_seconds\x18\x04 \x01(\x02\x12&\n\x1en_bits_server_n_packets_server\x18\x05 \x01(\x02\x12&\n\x1en_bits_client_n_packets_client\x18\x06 \x01(\x02\x12)\n!n_packets_server_n_packets_client\x18\x07 \x01(\x02\x12#\n\x1bn_bits_server_n_bits_client\x18\x08 \x01(\x02\x12\x0c\n\x04ip_o\x18\t \x01(\t\x12\x0e\n\x06port_o\x18\n \x01(\t\x12\x0c\n\x04ip_d\x18\x0b \x01(\t\x12\x0e\n\x06port_d\x18\x0c \x01(\t\x12\x0f\n\x07\x66low_id\x18\r \x01(\t\x12\x10\n\x08protocol\x18\x0e \x01(\t\x12\x12\n\ntime_start\x18\x0f \x01(\x02\x12\x10\n\x08time_end\x18\x10 \x01(\x02\"\x18\n\x05\x45mpty\x12\x0f\n\x07message\x18\x01 \x01(\t\"\xe4\x01\n&L3CentralizedattackdetectorModelOutput\x12\x12\n\nconfidence\x18\x01 \x01(\x02\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x0c\n\x04ip_o\x18\x03 \x01(\t\x12\x10\n\x08tag_name\x18\x04 \x01(\t\x12\x0b\n\x03tag\x18\x05 \x01(\x05\x12\x0f\n\x07\x66low_id\x18\x06 \x01(\t\x12\x10\n\x08protocol\x18\x07 \x01(\t\x12\x0e\n\x06port_d\x18\x08 \x01(\t\x12\r\n\x05ml_id\x18\t \x01(\t\x12\x12\n\ntime_start\x18\n \x01(\x02\x12\x10\n\x08time_end\x18\x0b \x01(\x02\x32\x99\x01\n\x1bL3Centralizedattackdetector\x12:\n\tSendInput\x12#.L3CentralizedattackdetectorMetrics\x1a\x06.Empty\"\x00\x12>\n\tGetOutput\x12\x06.Empty\x1a\'.L3CentralizedattackdetectorModelOutput\"\x00\x62\x06proto3'
 )
 
 
 
 
-_MODELINPUT = _descriptor.Descriptor(
-  name='ModelInput',
-  full_name='ModelInput',
+_L3CENTRALIZEDATTACKDETECTORMETRICS = _descriptor.Descriptor(
+  name='L3CentralizedattackdetectorMetrics',
+  full_name='L3CentralizedattackdetectorMetrics',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='n_packets_server_seconds', full_name='ModelInput.n_packets_server_seconds', index=0,
+      name='n_packets_server_seconds', full_name='L3CentralizedattackdetectorMetrics.n_packets_server_seconds', index=0,
       number=1, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_packets_client_seconds', full_name='ModelInput.n_packets_client_seconds', index=1,
+      name='n_packets_client_seconds', full_name='L3CentralizedattackdetectorMetrics.n_packets_client_seconds', index=1,
       number=2, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_server_seconds', full_name='ModelInput.n_bits_server_seconds', index=2,
+      name='n_bits_server_seconds', full_name='L3CentralizedattackdetectorMetrics.n_bits_server_seconds', index=2,
       number=3, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_client_seconds', full_name='ModelInput.n_bits_client_seconds', index=3,
+      name='n_bits_client_seconds', full_name='L3CentralizedattackdetectorMetrics.n_bits_client_seconds', index=3,
       number=4, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_server_n_packets_server', full_name='ModelInput.n_bits_server_n_packets_server', index=4,
+      name='n_bits_server_n_packets_server', full_name='L3CentralizedattackdetectorMetrics.n_bits_server_n_packets_server', index=4,
       number=5, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_client_n_packets_client', full_name='ModelInput.n_bits_client_n_packets_client', index=5,
+      name='n_bits_client_n_packets_client', full_name='L3CentralizedattackdetectorMetrics.n_bits_client_n_packets_client', index=5,
       number=6, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_packets_server_n_packets_client', full_name='ModelInput.n_packets_server_n_packets_client', index=6,
+      name='n_packets_server_n_packets_client', full_name='L3CentralizedattackdetectorMetrics.n_packets_server_n_packets_client', index=6,
       number=7, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_server_n_bits_client', full_name='ModelInput.n_bits_server_n_bits_client', index=7,
+      name='n_bits_server_n_bits_client', full_name='L3CentralizedattackdetectorMetrics.n_bits_server_n_bits_client', index=7,
       number=8, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ip_o', full_name='ModelInput.ip_o', index=8,
+      name='ip_o', full_name='L3CentralizedattackdetectorMetrics.ip_o', index=8,
       number=9, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='port_o', full_name='ModelInput.port_o', index=9,
+      name='port_o', full_name='L3CentralizedattackdetectorMetrics.port_o', index=9,
       number=10, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ip_d', full_name='ModelInput.ip_d', index=10,
+      name='ip_d', full_name='L3CentralizedattackdetectorMetrics.ip_d', index=10,
       number=11, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='port_d', full_name='ModelInput.port_d', index=11,
+      name='port_d', full_name='L3CentralizedattackdetectorMetrics.port_d', index=11,
       number=12, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='flow_id', full_name='ModelInput.flow_id', index=12,
+      name='flow_id', full_name='L3CentralizedattackdetectorMetrics.flow_id', index=12,
       number=13, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='protocol', full_name='ModelInput.protocol', index=13,
+      name='protocol', full_name='L3CentralizedattackdetectorMetrics.protocol', index=13,
       number=14, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_start', full_name='ModelInput.time_start', index=14,
+      name='time_start', full_name='L3CentralizedattackdetectorMetrics.time_start', index=14,
       number=15, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_end', full_name='ModelInput.time_end', index=15,
+      name='time_end', full_name='L3CentralizedattackdetectorMetrics.time_end', index=15,
       number=16, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
@@ -156,19 +156,9 @@ _MODELINPUT = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_time_start', full_name='ModelInput._time_start',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_end', full_name='ModelInput._time_end',
-      index=1, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
   ],
   serialized_start=39,
-  serialized_end=512,
+  serialized_end=498,
 )
 
 
@@ -198,97 +188,92 @@ _EMPTY = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_message', full_name='Empty._message',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
   ],
-  serialized_start=514,
-  serialized_end=555,
+  serialized_start=500,
+  serialized_end=524,
 )
 
 
-_MODELOUTPUT = _descriptor.Descriptor(
-  name='ModelOutput',
-  full_name='ModelOutput',
+_L3CENTRALIZEDATTACKDETECTORMODELOUTPUT = _descriptor.Descriptor(
+  name='L3CentralizedattackdetectorModelOutput',
+  full_name='L3CentralizedattackdetectorModelOutput',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='confidence', full_name='ModelOutput.confidence', index=0,
+      name='confidence', full_name='L3CentralizedattackdetectorModelOutput.confidence', index=0,
       number=1, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='timestamp', full_name='ModelOutput.timestamp', index=1,
+      name='timestamp', full_name='L3CentralizedattackdetectorModelOutput.timestamp', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ip_o', full_name='ModelOutput.ip_o', index=2,
+      name='ip_o', full_name='L3CentralizedattackdetectorModelOutput.ip_o', index=2,
       number=3, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='tag_name', full_name='ModelOutput.tag_name', index=3,
+      name='tag_name', full_name='L3CentralizedattackdetectorModelOutput.tag_name', index=3,
       number=4, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='tag', full_name='ModelOutput.tag', index=4,
+      name='tag', full_name='L3CentralizedattackdetectorModelOutput.tag', index=4,
       number=5, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='flow_id', full_name='ModelOutput.flow_id', index=5,
+      name='flow_id', full_name='L3CentralizedattackdetectorModelOutput.flow_id', index=5,
       number=6, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='protocol', full_name='ModelOutput.protocol', index=6,
+      name='protocol', full_name='L3CentralizedattackdetectorModelOutput.protocol', index=6,
       number=7, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='port_d', full_name='ModelOutput.port_d', index=7,
+      name='port_d', full_name='L3CentralizedattackdetectorModelOutput.port_d', index=7,
       number=8, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ml_id', full_name='ModelOutput.ml_id', index=8,
+      name='ml_id', full_name='L3CentralizedattackdetectorModelOutput.ml_id', index=8,
       number=9, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_start', full_name='ModelOutput.time_start', index=9,
+      name='time_start', full_name='L3CentralizedattackdetectorModelOutput.time_start', index=9,
       number=10, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_end', full_name='ModelOutput.time_end', index=10,
+      name='time_end', full_name='L3CentralizedattackdetectorModelOutput.time_end', index=10,
       number=11, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
@@ -305,55 +290,22 @@ _MODELOUTPUT = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_ml_id', full_name='ModelOutput._ml_id',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_start', full_name='ModelOutput._time_start',
-      index=1, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_end', full_name='ModelOutput._time_end',
-      index=2, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
   ],
-  serialized_start=558,
-  serialized_end=812,
+  serialized_start=527,
+  serialized_end=755,
 )
 
-_MODELINPUT.oneofs_by_name['_time_start'].fields.append(
-  _MODELINPUT.fields_by_name['time_start'])
-_MODELINPUT.fields_by_name['time_start'].containing_oneof = _MODELINPUT.oneofs_by_name['_time_start']
-_MODELINPUT.oneofs_by_name['_time_end'].fields.append(
-  _MODELINPUT.fields_by_name['time_end'])
-_MODELINPUT.fields_by_name['time_end'].containing_oneof = _MODELINPUT.oneofs_by_name['_time_end']
-_EMPTY.oneofs_by_name['_message'].fields.append(
-  _EMPTY.fields_by_name['message'])
-_EMPTY.fields_by_name['message'].containing_oneof = _EMPTY.oneofs_by_name['_message']
-_MODELOUTPUT.oneofs_by_name['_ml_id'].fields.append(
-  _MODELOUTPUT.fields_by_name['ml_id'])
-_MODELOUTPUT.fields_by_name['ml_id'].containing_oneof = _MODELOUTPUT.oneofs_by_name['_ml_id']
-_MODELOUTPUT.oneofs_by_name['_time_start'].fields.append(
-  _MODELOUTPUT.fields_by_name['time_start'])
-_MODELOUTPUT.fields_by_name['time_start'].containing_oneof = _MODELOUTPUT.oneofs_by_name['_time_start']
-_MODELOUTPUT.oneofs_by_name['_time_end'].fields.append(
-  _MODELOUTPUT.fields_by_name['time_end'])
-_MODELOUTPUT.fields_by_name['time_end'].containing_oneof = _MODELOUTPUT.oneofs_by_name['_time_end']
-DESCRIPTOR.message_types_by_name['ModelInput'] = _MODELINPUT
+DESCRIPTOR.message_types_by_name['L3CentralizedattackdetectorMetrics'] = _L3CENTRALIZEDATTACKDETECTORMETRICS
 DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
-DESCRIPTOR.message_types_by_name['ModelOutput'] = _MODELOUTPUT
+DESCRIPTOR.message_types_by_name['L3CentralizedattackdetectorModelOutput'] = _L3CENTRALIZEDATTACKDETECTORMODELOUTPUT
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
-ModelInput = _reflection.GeneratedProtocolMessageType('ModelInput', (_message.Message,), {
-  'DESCRIPTOR' : _MODELINPUT,
+L3CentralizedattackdetectorMetrics = _reflection.GeneratedProtocolMessageType('L3CentralizedattackdetectorMetrics', (_message.Message,), {
+  'DESCRIPTOR' : _L3CENTRALIZEDATTACKDETECTORMETRICS,
   '__module__' : 'l3_centralizedattackdetector_pb2'
-  # @@protoc_insertion_point(class_scope:ModelInput)
+  # @@protoc_insertion_point(class_scope:L3CentralizedattackdetectorMetrics)
   })
-_sym_db.RegisterMessage(ModelInput)
+_sym_db.RegisterMessage(L3CentralizedattackdetectorMetrics)
 
 Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
   'DESCRIPTOR' : _EMPTY,
@@ -362,12 +314,12 @@ Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
   })
 _sym_db.RegisterMessage(Empty)
 
-ModelOutput = _reflection.GeneratedProtocolMessageType('ModelOutput', (_message.Message,), {
-  'DESCRIPTOR' : _MODELOUTPUT,
+L3CentralizedattackdetectorModelOutput = _reflection.GeneratedProtocolMessageType('L3CentralizedattackdetectorModelOutput', (_message.Message,), {
+  'DESCRIPTOR' : _L3CENTRALIZEDATTACKDETECTORMODELOUTPUT,
   '__module__' : 'l3_centralizedattackdetector_pb2'
-  # @@protoc_insertion_point(class_scope:ModelOutput)
+  # @@protoc_insertion_point(class_scope:L3CentralizedattackdetectorModelOutput)
   })
-_sym_db.RegisterMessage(ModelOutput)
+_sym_db.RegisterMessage(L3CentralizedattackdetectorModelOutput)
 
 
 
@@ -378,15 +330,15 @@ _L3CENTRALIZEDATTACKDETECTOR = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=814,
-  serialized_end=916,
+  serialized_start=758,
+  serialized_end=911,
   methods=[
   _descriptor.MethodDescriptor(
     name='SendInput',
     full_name='L3Centralizedattackdetector.SendInput',
     index=0,
     containing_service=None,
-    input_type=_MODELINPUT,
+    input_type=_L3CENTRALIZEDATTACKDETECTORMETRICS,
     output_type=_EMPTY,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
@@ -397,7 +349,7 @@ _L3CENTRALIZEDATTACKDETECTOR = _descriptor.ServiceDescriptor(
     index=1,
     containing_service=None,
     input_type=_EMPTY,
-    output_type=_MODELOUTPUT,
+    output_type=_L3CENTRALIZEDATTACKDETECTORMODELOUTPUT,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
diff --git a/src/l3_centralizedattackdetector/proto/l3_centralizedattackdetector_pb2_grpc.py b/src/l3_centralizedattackdetector/proto/l3_centralizedattackdetector_pb2_grpc.py
index eaff68364..29136b4da 100644
--- a/src/l3_centralizedattackdetector/proto/l3_centralizedattackdetector_pb2_grpc.py
+++ b/src/l3_centralizedattackdetector/proto/l3_centralizedattackdetector_pb2_grpc.py
@@ -16,13 +16,13 @@ class L3CentralizedattackdetectorStub(object):
         """
         self.SendInput = channel.unary_unary(
                 '/L3Centralizedattackdetector/SendInput',
-                request_serializer=l3__centralizedattackdetector__pb2.ModelInput.SerializeToString,
+                request_serializer=l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorMetrics.SerializeToString,
                 response_deserializer=l3__centralizedattackdetector__pb2.Empty.FromString,
                 )
         self.GetOutput = channel.unary_unary(
                 '/L3Centralizedattackdetector/GetOutput',
                 request_serializer=l3__centralizedattackdetector__pb2.Empty.SerializeToString,
-                response_deserializer=l3__centralizedattackdetector__pb2.ModelOutput.FromString,
+                response_deserializer=l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorModelOutput.FromString,
                 )
 
 
@@ -48,13 +48,13 @@ def add_L3CentralizedattackdetectorServicer_to_server(servicer, server):
     rpc_method_handlers = {
             'SendInput': grpc.unary_unary_rpc_method_handler(
                     servicer.SendInput,
-                    request_deserializer=l3__centralizedattackdetector__pb2.ModelInput.FromString,
+                    request_deserializer=l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorMetrics.FromString,
                     response_serializer=l3__centralizedattackdetector__pb2.Empty.SerializeToString,
             ),
             'GetOutput': grpc.unary_unary_rpc_method_handler(
                     servicer.GetOutput,
                     request_deserializer=l3__centralizedattackdetector__pb2.Empty.FromString,
-                    response_serializer=l3__centralizedattackdetector__pb2.ModelOutput.SerializeToString,
+                    response_serializer=l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorModelOutput.SerializeToString,
             ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
@@ -78,7 +78,7 @@ class L3Centralizedattackdetector(object):
             timeout=None,
             metadata=None):
         return grpc.experimental.unary_unary(request, target, '/L3Centralizedattackdetector/SendInput',
-            l3__centralizedattackdetector__pb2.ModelInput.SerializeToString,
+            l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorMetrics.SerializeToString,
             l3__centralizedattackdetector__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -96,6 +96,6 @@ class L3Centralizedattackdetector(object):
             metadata=None):
         return grpc.experimental.unary_unary(request, target, '/L3Centralizedattackdetector/GetOutput',
             l3__centralizedattackdetector__pb2.Empty.SerializeToString,
-            l3__centralizedattackdetector__pb2.ModelOutput.FromString,
+            l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorModelOutput.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/l3_distributedattackdetector/genproto.sh b/src/l3_distributedattackdetector/genproto.sh
old mode 100644
new mode 100755
index 9ca93e30e..c1f54c0dc
--- a/src/l3_distributedattackdetector/genproto.sh
+++ b/src/l3_distributedattackdetector/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,14 +14,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto l3_centralizedattackdetector.proto
 
diff --git a/src/l3_distributedattackdetector/proto/l3_centralizedattackdetector_pb2.py b/src/l3_distributedattackdetector/proto/l3_centralizedattackdetector_pb2.py
index cafbc6bf8..517fdb84b 100644
--- a/src/l3_distributedattackdetector/proto/l3_centralizedattackdetector_pb2.py
+++ b/src/l3_distributedattackdetector/proto/l3_centralizedattackdetector_pb2.py
@@ -19,127 +19,127 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\"l3_centralizedattackdetector.proto\"\xd9\x03\n\nModelInput\x12 \n\x18n_packets_server_seconds\x18\x01 \x01(\x02\x12 \n\x18n_packets_client_seconds\x18\x02 \x01(\x02\x12\x1d\n\x15n_bits_server_seconds\x18\x03 \x01(\x02\x12\x1d\n\x15n_bits_client_seconds\x18\x04 \x01(\x02\x12&\n\x1en_bits_server_n_packets_server\x18\x05 \x01(\x02\x12&\n\x1en_bits_client_n_packets_client\x18\x06 \x01(\x02\x12)\n!n_packets_server_n_packets_client\x18\x07 \x01(\x02\x12#\n\x1bn_bits_server_n_bits_client\x18\x08 \x01(\x02\x12\x0c\n\x04ip_o\x18\t \x01(\t\x12\x0e\n\x06port_o\x18\n \x01(\t\x12\x0c\n\x04ip_d\x18\x0b \x01(\t\x12\x0e\n\x06port_d\x18\x0c \x01(\t\x12\x0f\n\x07\x66low_id\x18\r \x01(\t\x12\x10\n\x08protocol\x18\x0e \x01(\t\x12\x17\n\ntime_start\x18\x0f \x01(\x02H\x00\x88\x01\x01\x12\x15\n\x08time_end\x18\x10 \x01(\x02H\x01\x88\x01\x01\x42\r\n\x0b_time_startB\x0b\n\t_time_end\")\n\x05\x45mpty\x12\x14\n\x07message\x18\x01 \x01(\tH\x00\x88\x01\x01\x42\n\n\x08_message\"\xfe\x01\n\x0bModelOutput\x12\x12\n\nconfidence\x18\x01 \x01(\x02\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x0c\n\x04ip_o\x18\x03 \x01(\t\x12\x10\n\x08tag_name\x18\x04 \x01(\t\x12\x0b\n\x03tag\x18\x05 \x01(\x05\x12\x0f\n\x07\x66low_id\x18\x06 \x01(\t\x12\x10\n\x08protocol\x18\x07 \x01(\t\x12\x0e\n\x06port_d\x18\x08 \x01(\t\x12\x12\n\x05ml_id\x18\t \x01(\tH\x00\x88\x01\x01\x12\x17\n\ntime_start\x18\n \x01(\x02H\x01\x88\x01\x01\x12\x15\n\x08time_end\x18\x0b \x01(\x02H\x02\x88\x01\x01\x42\x08\n\x06_ml_idB\r\n\x0b_time_startB\x0b\n\t_time_end2f\n\x1bL3Centralizedattackdetector\x12\"\n\tSendInput\x12\x0b.ModelInput\x1a\x06.Empty\"\x00\x12#\n\tGetOutput\x12\x06.Empty\x1a\x0c.ModelOutput\"\x00\x62\x06proto3'
+  serialized_pb=b'\n\"l3_centralizedattackdetector.proto\"\xcb\x03\n\"L3CentralizedattackdetectorMetrics\x12 \n\x18n_packets_server_seconds\x18\x01 \x01(\x02\x12 \n\x18n_packets_client_seconds\x18\x02 \x01(\x02\x12\x1d\n\x15n_bits_server_seconds\x18\x03 \x01(\x02\x12\x1d\n\x15n_bits_client_seconds\x18\x04 \x01(\x02\x12&\n\x1en_bits_server_n_packets_server\x18\x05 \x01(\x02\x12&\n\x1en_bits_client_n_packets_client\x18\x06 \x01(\x02\x12)\n!n_packets_server_n_packets_client\x18\x07 \x01(\x02\x12#\n\x1bn_bits_server_n_bits_client\x18\x08 \x01(\x02\x12\x0c\n\x04ip_o\x18\t \x01(\t\x12\x0e\n\x06port_o\x18\n \x01(\t\x12\x0c\n\x04ip_d\x18\x0b \x01(\t\x12\x0e\n\x06port_d\x18\x0c \x01(\t\x12\x0f\n\x07\x66low_id\x18\r \x01(\t\x12\x10\n\x08protocol\x18\x0e \x01(\t\x12\x12\n\ntime_start\x18\x0f \x01(\x02\x12\x10\n\x08time_end\x18\x10 \x01(\x02\"\x18\n\x05\x45mpty\x12\x0f\n\x07message\x18\x01 \x01(\t\"\xe4\x01\n&L3CentralizedattackdetectorModelOutput\x12\x12\n\nconfidence\x18\x01 \x01(\x02\x12\x11\n\ttimestamp\x18\x02 \x01(\t\x12\x0c\n\x04ip_o\x18\x03 \x01(\t\x12\x10\n\x08tag_name\x18\x04 \x01(\t\x12\x0b\n\x03tag\x18\x05 \x01(\x05\x12\x0f\n\x07\x66low_id\x18\x06 \x01(\t\x12\x10\n\x08protocol\x18\x07 \x01(\t\x12\x0e\n\x06port_d\x18\x08 \x01(\t\x12\r\n\x05ml_id\x18\t \x01(\t\x12\x12\n\ntime_start\x18\n \x01(\x02\x12\x10\n\x08time_end\x18\x0b \x01(\x02\x32\x99\x01\n\x1bL3Centralizedattackdetector\x12:\n\tSendInput\x12#.L3CentralizedattackdetectorMetrics\x1a\x06.Empty\"\x00\x12>\n\tGetOutput\x12\x06.Empty\x1a\'.L3CentralizedattackdetectorModelOutput\"\x00\x62\x06proto3'
 )
 
 
 
 
-_MODELINPUT = _descriptor.Descriptor(
-  name='ModelInput',
-  full_name='ModelInput',
+_L3CENTRALIZEDATTACKDETECTORMETRICS = _descriptor.Descriptor(
+  name='L3CentralizedattackdetectorMetrics',
+  full_name='L3CentralizedattackdetectorMetrics',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='n_packets_server_seconds', full_name='ModelInput.n_packets_server_seconds', index=0,
+      name='n_packets_server_seconds', full_name='L3CentralizedattackdetectorMetrics.n_packets_server_seconds', index=0,
       number=1, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_packets_client_seconds', full_name='ModelInput.n_packets_client_seconds', index=1,
+      name='n_packets_client_seconds', full_name='L3CentralizedattackdetectorMetrics.n_packets_client_seconds', index=1,
       number=2, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_server_seconds', full_name='ModelInput.n_bits_server_seconds', index=2,
+      name='n_bits_server_seconds', full_name='L3CentralizedattackdetectorMetrics.n_bits_server_seconds', index=2,
       number=3, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_client_seconds', full_name='ModelInput.n_bits_client_seconds', index=3,
+      name='n_bits_client_seconds', full_name='L3CentralizedattackdetectorMetrics.n_bits_client_seconds', index=3,
       number=4, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_server_n_packets_server', full_name='ModelInput.n_bits_server_n_packets_server', index=4,
+      name='n_bits_server_n_packets_server', full_name='L3CentralizedattackdetectorMetrics.n_bits_server_n_packets_server', index=4,
       number=5, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_client_n_packets_client', full_name='ModelInput.n_bits_client_n_packets_client', index=5,
+      name='n_bits_client_n_packets_client', full_name='L3CentralizedattackdetectorMetrics.n_bits_client_n_packets_client', index=5,
       number=6, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_packets_server_n_packets_client', full_name='ModelInput.n_packets_server_n_packets_client', index=6,
+      name='n_packets_server_n_packets_client', full_name='L3CentralizedattackdetectorMetrics.n_packets_server_n_packets_client', index=6,
       number=7, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='n_bits_server_n_bits_client', full_name='ModelInput.n_bits_server_n_bits_client', index=7,
+      name='n_bits_server_n_bits_client', full_name='L3CentralizedattackdetectorMetrics.n_bits_server_n_bits_client', index=7,
       number=8, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ip_o', full_name='ModelInput.ip_o', index=8,
+      name='ip_o', full_name='L3CentralizedattackdetectorMetrics.ip_o', index=8,
       number=9, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='port_o', full_name='ModelInput.port_o', index=9,
+      name='port_o', full_name='L3CentralizedattackdetectorMetrics.port_o', index=9,
       number=10, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ip_d', full_name='ModelInput.ip_d', index=10,
+      name='ip_d', full_name='L3CentralizedattackdetectorMetrics.ip_d', index=10,
       number=11, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='port_d', full_name='ModelInput.port_d', index=11,
+      name='port_d', full_name='L3CentralizedattackdetectorMetrics.port_d', index=11,
       number=12, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='flow_id', full_name='ModelInput.flow_id', index=12,
+      name='flow_id', full_name='L3CentralizedattackdetectorMetrics.flow_id', index=12,
       number=13, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='protocol', full_name='ModelInput.protocol', index=13,
+      name='protocol', full_name='L3CentralizedattackdetectorMetrics.protocol', index=13,
       number=14, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_start', full_name='ModelInput.time_start', index=14,
+      name='time_start', full_name='L3CentralizedattackdetectorMetrics.time_start', index=14,
       number=15, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_end', full_name='ModelInput.time_end', index=15,
+      name='time_end', full_name='L3CentralizedattackdetectorMetrics.time_end', index=15,
       number=16, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
@@ -156,19 +156,9 @@ _MODELINPUT = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_time_start', full_name='ModelInput._time_start',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_end', full_name='ModelInput._time_end',
-      index=1, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
   ],
   serialized_start=39,
-  serialized_end=512,
+  serialized_end=498,
 )
 
 
@@ -198,97 +188,92 @@ _EMPTY = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_message', full_name='Empty._message',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
   ],
-  serialized_start=514,
-  serialized_end=555,
+  serialized_start=500,
+  serialized_end=524,
 )
 
 
-_MODELOUTPUT = _descriptor.Descriptor(
-  name='ModelOutput',
-  full_name='ModelOutput',
+_L3CENTRALIZEDATTACKDETECTORMODELOUTPUT = _descriptor.Descriptor(
+  name='L3CentralizedattackdetectorModelOutput',
+  full_name='L3CentralizedattackdetectorModelOutput',
   filename=None,
   file=DESCRIPTOR,
   containing_type=None,
   create_key=_descriptor._internal_create_key,
   fields=[
     _descriptor.FieldDescriptor(
-      name='confidence', full_name='ModelOutput.confidence', index=0,
+      name='confidence', full_name='L3CentralizedattackdetectorModelOutput.confidence', index=0,
       number=1, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='timestamp', full_name='ModelOutput.timestamp', index=1,
+      name='timestamp', full_name='L3CentralizedattackdetectorModelOutput.timestamp', index=1,
       number=2, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ip_o', full_name='ModelOutput.ip_o', index=2,
+      name='ip_o', full_name='L3CentralizedattackdetectorModelOutput.ip_o', index=2,
       number=3, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='tag_name', full_name='ModelOutput.tag_name', index=3,
+      name='tag_name', full_name='L3CentralizedattackdetectorModelOutput.tag_name', index=3,
       number=4, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='tag', full_name='ModelOutput.tag', index=4,
+      name='tag', full_name='L3CentralizedattackdetectorModelOutput.tag', index=4,
       number=5, type=5, cpp_type=1, label=1,
       has_default_value=False, default_value=0,
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='flow_id', full_name='ModelOutput.flow_id', index=5,
+      name='flow_id', full_name='L3CentralizedattackdetectorModelOutput.flow_id', index=5,
       number=6, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='protocol', full_name='ModelOutput.protocol', index=6,
+      name='protocol', full_name='L3CentralizedattackdetectorModelOutput.protocol', index=6,
       number=7, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='port_d', full_name='ModelOutput.port_d', index=7,
+      name='port_d', full_name='L3CentralizedattackdetectorModelOutput.port_d', index=7,
       number=8, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='ml_id', full_name='ModelOutput.ml_id', index=8,
+      name='ml_id', full_name='L3CentralizedattackdetectorModelOutput.ml_id', index=8,
       number=9, type=9, cpp_type=9, label=1,
       has_default_value=False, default_value=b"".decode('utf-8'),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_start', full_name='ModelOutput.time_start', index=9,
+      name='time_start', full_name='L3CentralizedattackdetectorModelOutput.time_start', index=9,
       number=10, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
       is_extension=False, extension_scope=None,
       serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
     _descriptor.FieldDescriptor(
-      name='time_end', full_name='ModelOutput.time_end', index=10,
+      name='time_end', full_name='L3CentralizedattackdetectorModelOutput.time_end', index=10,
       number=11, type=2, cpp_type=6, label=1,
       has_default_value=False, default_value=float(0),
       message_type=None, enum_type=None, containing_type=None,
@@ -305,55 +290,22 @@ _MODELOUTPUT = _descriptor.Descriptor(
   syntax='proto3',
   extension_ranges=[],
   oneofs=[
-    _descriptor.OneofDescriptor(
-      name='_ml_id', full_name='ModelOutput._ml_id',
-      index=0, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_start', full_name='ModelOutput._time_start',
-      index=1, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
-    _descriptor.OneofDescriptor(
-      name='_time_end', full_name='ModelOutput._time_end',
-      index=2, containing_type=None,
-      create_key=_descriptor._internal_create_key,
-    fields=[]),
   ],
-  serialized_start=558,
-  serialized_end=812,
+  serialized_start=527,
+  serialized_end=755,
 )
 
-_MODELINPUT.oneofs_by_name['_time_start'].fields.append(
-  _MODELINPUT.fields_by_name['time_start'])
-_MODELINPUT.fields_by_name['time_start'].containing_oneof = _MODELINPUT.oneofs_by_name['_time_start']
-_MODELINPUT.oneofs_by_name['_time_end'].fields.append(
-  _MODELINPUT.fields_by_name['time_end'])
-_MODELINPUT.fields_by_name['time_end'].containing_oneof = _MODELINPUT.oneofs_by_name['_time_end']
-_EMPTY.oneofs_by_name['_message'].fields.append(
-  _EMPTY.fields_by_name['message'])
-_EMPTY.fields_by_name['message'].containing_oneof = _EMPTY.oneofs_by_name['_message']
-_MODELOUTPUT.oneofs_by_name['_ml_id'].fields.append(
-  _MODELOUTPUT.fields_by_name['ml_id'])
-_MODELOUTPUT.fields_by_name['ml_id'].containing_oneof = _MODELOUTPUT.oneofs_by_name['_ml_id']
-_MODELOUTPUT.oneofs_by_name['_time_start'].fields.append(
-  _MODELOUTPUT.fields_by_name['time_start'])
-_MODELOUTPUT.fields_by_name['time_start'].containing_oneof = _MODELOUTPUT.oneofs_by_name['_time_start']
-_MODELOUTPUT.oneofs_by_name['_time_end'].fields.append(
-  _MODELOUTPUT.fields_by_name['time_end'])
-_MODELOUTPUT.fields_by_name['time_end'].containing_oneof = _MODELOUTPUT.oneofs_by_name['_time_end']
-DESCRIPTOR.message_types_by_name['ModelInput'] = _MODELINPUT
+DESCRIPTOR.message_types_by_name['L3CentralizedattackdetectorMetrics'] = _L3CENTRALIZEDATTACKDETECTORMETRICS
 DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
-DESCRIPTOR.message_types_by_name['ModelOutput'] = _MODELOUTPUT
+DESCRIPTOR.message_types_by_name['L3CentralizedattackdetectorModelOutput'] = _L3CENTRALIZEDATTACKDETECTORMODELOUTPUT
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
-ModelInput = _reflection.GeneratedProtocolMessageType('ModelInput', (_message.Message,), {
-  'DESCRIPTOR' : _MODELINPUT,
+L3CentralizedattackdetectorMetrics = _reflection.GeneratedProtocolMessageType('L3CentralizedattackdetectorMetrics', (_message.Message,), {
+  'DESCRIPTOR' : _L3CENTRALIZEDATTACKDETECTORMETRICS,
   '__module__' : 'l3_centralizedattackdetector_pb2'
-  # @@protoc_insertion_point(class_scope:ModelInput)
+  # @@protoc_insertion_point(class_scope:L3CentralizedattackdetectorMetrics)
   })
-_sym_db.RegisterMessage(ModelInput)
+_sym_db.RegisterMessage(L3CentralizedattackdetectorMetrics)
 
 Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
   'DESCRIPTOR' : _EMPTY,
@@ -362,12 +314,12 @@ Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
   })
 _sym_db.RegisterMessage(Empty)
 
-ModelOutput = _reflection.GeneratedProtocolMessageType('ModelOutput', (_message.Message,), {
-  'DESCRIPTOR' : _MODELOUTPUT,
+L3CentralizedattackdetectorModelOutput = _reflection.GeneratedProtocolMessageType('L3CentralizedattackdetectorModelOutput', (_message.Message,), {
+  'DESCRIPTOR' : _L3CENTRALIZEDATTACKDETECTORMODELOUTPUT,
   '__module__' : 'l3_centralizedattackdetector_pb2'
-  # @@protoc_insertion_point(class_scope:ModelOutput)
+  # @@protoc_insertion_point(class_scope:L3CentralizedattackdetectorModelOutput)
   })
-_sym_db.RegisterMessage(ModelOutput)
+_sym_db.RegisterMessage(L3CentralizedattackdetectorModelOutput)
 
 
 
@@ -378,15 +330,15 @@ _L3CENTRALIZEDATTACKDETECTOR = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=814,
-  serialized_end=916,
+  serialized_start=758,
+  serialized_end=911,
   methods=[
   _descriptor.MethodDescriptor(
     name='SendInput',
     full_name='L3Centralizedattackdetector.SendInput',
     index=0,
     containing_service=None,
-    input_type=_MODELINPUT,
+    input_type=_L3CENTRALIZEDATTACKDETECTORMETRICS,
     output_type=_EMPTY,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
@@ -397,7 +349,7 @@ _L3CENTRALIZEDATTACKDETECTOR = _descriptor.ServiceDescriptor(
     index=1,
     containing_service=None,
     input_type=_EMPTY,
-    output_type=_MODELOUTPUT,
+    output_type=_L3CENTRALIZEDATTACKDETECTORMODELOUTPUT,
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
diff --git a/src/l3_distributedattackdetector/proto/l3_centralizedattackdetector_pb2_grpc.py b/src/l3_distributedattackdetector/proto/l3_centralizedattackdetector_pb2_grpc.py
index eaff68364..29136b4da 100644
--- a/src/l3_distributedattackdetector/proto/l3_centralizedattackdetector_pb2_grpc.py
+++ b/src/l3_distributedattackdetector/proto/l3_centralizedattackdetector_pb2_grpc.py
@@ -16,13 +16,13 @@ class L3CentralizedattackdetectorStub(object):
         """
         self.SendInput = channel.unary_unary(
                 '/L3Centralizedattackdetector/SendInput',
-                request_serializer=l3__centralizedattackdetector__pb2.ModelInput.SerializeToString,
+                request_serializer=l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorMetrics.SerializeToString,
                 response_deserializer=l3__centralizedattackdetector__pb2.Empty.FromString,
                 )
         self.GetOutput = channel.unary_unary(
                 '/L3Centralizedattackdetector/GetOutput',
                 request_serializer=l3__centralizedattackdetector__pb2.Empty.SerializeToString,
-                response_deserializer=l3__centralizedattackdetector__pb2.ModelOutput.FromString,
+                response_deserializer=l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorModelOutput.FromString,
                 )
 
 
@@ -48,13 +48,13 @@ def add_L3CentralizedattackdetectorServicer_to_server(servicer, server):
     rpc_method_handlers = {
             'SendInput': grpc.unary_unary_rpc_method_handler(
                     servicer.SendInput,
-                    request_deserializer=l3__centralizedattackdetector__pb2.ModelInput.FromString,
+                    request_deserializer=l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorMetrics.FromString,
                     response_serializer=l3__centralizedattackdetector__pb2.Empty.SerializeToString,
             ),
             'GetOutput': grpc.unary_unary_rpc_method_handler(
                     servicer.GetOutput,
                     request_deserializer=l3__centralizedattackdetector__pb2.Empty.FromString,
-                    response_serializer=l3__centralizedattackdetector__pb2.ModelOutput.SerializeToString,
+                    response_serializer=l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorModelOutput.SerializeToString,
             ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
@@ -78,7 +78,7 @@ class L3Centralizedattackdetector(object):
             timeout=None,
             metadata=None):
         return grpc.experimental.unary_unary(request, target, '/L3Centralizedattackdetector/SendInput',
-            l3__centralizedattackdetector__pb2.ModelInput.SerializeToString,
+            l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorMetrics.SerializeToString,
             l3__centralizedattackdetector__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
@@ -96,6 +96,6 @@ class L3Centralizedattackdetector(object):
             metadata=None):
         return grpc.experimental.unary_unary(request, target, '/L3Centralizedattackdetector/GetOutput',
             l3__centralizedattackdetector__pb2.Empty.SerializeToString,
-            l3__centralizedattackdetector__pb2.ModelOutput.FromString,
+            l3__centralizedattackdetector__pb2.L3CentralizedattackdetectorModelOutput.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/monitoring/genproto.sh b/src/monitoring/genproto.sh
index b37b49ba2..793e40ad2 100755
--- a/src/monitoring/genproto.sh
+++ b/src/monitoring/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -19,7 +19,22 @@ cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto monitoring.proto
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
diff --git a/src/monitoring/proto/context_pb2.py b/src/monitoring/proto/context_pb2.py
index 68602b16f..50d501d3a 100644
--- a/src/monitoring/proto/context_pb2.py
+++ b/src/monitoring/proto/context_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xad\x10\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
   ,
   dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
 
@@ -55,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3703,
-  serialized_end=3809,
+  serialized_start=4310,
+  serialized_end=4416,
 )
 _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
 
@@ -101,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3812,
-  serialized_end=4009,
+  serialized_start=4419,
+  serialized_end=4616,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
 
@@ -132,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4012,
-  serialized_end=4155,
+  serialized_start=4619,
+  serialized_end=4762,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
 
@@ -168,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4158,
-  serialized_end=4287,
+  serialized_start=4765,
+  serialized_end=4894,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
 
@@ -204,12 +204,53 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4290,
-  serialized_end=4426,
+  serialized_start=4897,
+  serialized_end=5033,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
 
 ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
 _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   name='ConfigActionEnum',
   full_name='context.ConfigActionEnum',
@@ -235,8 +276,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4428,
-  serialized_end=4521,
+  serialized_start=5177,
+  serialized_end=5270,
 )
 _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
 
@@ -262,6 +303,11 @@ SERVICESTATUS_UNDEFINED = 0
 SERVICESTATUS_PLANNED = 1
 SERVICESTATUS_ACTIVE = 2
 SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
 CONFIGACTION_UNDEFINED = 0
 CONFIGACTION_SET = 1
 CONFIGACTION_DELETE = 2
@@ -1421,6 +1467,247 @@ _SERVICEEVENT = _descriptor.Descriptor(
 )
 
 
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
 _CONNECTIONID = _descriptor.Descriptor(
   name='ConnectionId',
   full_name='context.ConnectionId',
@@ -1448,8 +1735,8 @@ _CONNECTIONID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2604,
-  serialized_end=2658,
+  serialized_start=3211,
+  serialized_end=3265,
 )
 
 
@@ -1501,8 +1788,8 @@ _CONNECTION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2661,
-  serialized_end=2857,
+  serialized_start=3268,
+  serialized_end=3464,
 )
 
 
@@ -1533,8 +1820,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2859,
-  serialized_end=2924,
+  serialized_start=3466,
+  serialized_end=3531,
 )
 
 
@@ -1565,8 +1852,8 @@ _CONNECTIONLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2926,
-  serialized_end=2984,
+  serialized_start=3533,
+  serialized_end=3591,
 )
 
 
@@ -1604,8 +1891,8 @@ _CONNECTIONEVENT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2986,
-  serialized_end=3080,
+  serialized_start=3593,
+  serialized_end=3687,
 )
 
 
@@ -1650,8 +1937,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3083,
-  serialized_end=3213,
+  serialized_start=3690,
+  serialized_end=3820,
 )
 
 
@@ -1696,8 +1983,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3216,
-  serialized_end=3350,
+  serialized_start=3823,
+  serialized_end=3957,
 )
 
 
@@ -1742,8 +2029,8 @@ _CONFIGRULE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3352,
-  serialized_end=3453,
+  serialized_start=3959,
+  serialized_end=4060,
 )
 
 
@@ -1781,8 +2068,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3455,
-  serialized_end=3518,
+  serialized_start=4062,
+  serialized_end=4125,
 )
 
 
@@ -1827,8 +2114,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3520,
-  serialized_end=3614,
+  serialized_start=4127,
+  serialized_end=4221,
 )
 
 
@@ -1866,8 +2153,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3616,
-  serialized_end=3701,
+  serialized_start=4223,
+  serialized_end=4308,
 )
 
 _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
@@ -1921,6 +2208,19 @@ _SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
 _SERVICELIST.fields_by_name['services'].message_type = _SERVICE
 _SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
 _SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
 _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
 _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
 _CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
@@ -1969,6 +2269,12 @@ DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
 DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
 DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
 DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
 DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
 DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
 DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
@@ -1985,6 +2291,7 @@ DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
 DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
 DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
 DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
 DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -2205,6 +2512,48 @@ ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_messag
   })
 _sym_db.RegisterMessage(ServiceEvent)
 
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
 ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
   'DESCRIPTOR' : _CONNECTIONID,
   '__module__' : 'context_pb2'
@@ -2291,8 +2640,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=4524,
-  serialized_end=6617,
+  serialized_start=5273,
+  serialized_end=7688,
   methods=[
   _descriptor.MethodDescriptor(
     name='ListContextIds',
@@ -2594,10 +2943,70 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='ListConnectionIds',
     full_name='context.ContextService.ListConnectionIds',
-    index=30,
+    index=36,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONIDLIST,
@@ -2607,7 +3016,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='ListConnections',
     full_name='context.ContextService.ListConnections',
-    index=31,
+    index=37,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONLIST,
@@ -2617,7 +3026,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnection',
     full_name='context.ContextService.GetConnection',
-    index=32,
+    index=38,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_CONNECTION,
@@ -2627,7 +3036,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetConnection',
     full_name='context.ContextService.SetConnection',
-    index=33,
+    index=39,
     containing_service=None,
     input_type=_CONNECTION,
     output_type=_CONNECTIONID,
@@ -2637,7 +3046,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='RemoveConnection',
     full_name='context.ContextService.RemoveConnection',
-    index=34,
+    index=40,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_EMPTY,
@@ -2647,7 +3056,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnectionEvents',
     full_name='context.ContextService.GetConnectionEvents',
-    index=35,
+    index=41,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_CONNECTIONEVENT,
diff --git a/src/monitoring/requirements.in b/src/monitoring/requirements.in
index 77b66b794..839ea33af 100644
--- a/src/monitoring/requirements.in
+++ b/src/monitoring/requirements.in
@@ -1,16 +1,17 @@
-google-api-core
-grpcio-health-checking
-grpcio
-opencensus[stackdriver]
+#google-api-core
+grpcio==1.43.0
+grpcio-health-checking==1.43.0
+#opencensus[stackdriver]
 python-json-logger
-google-cloud-profiler
-numpy
-prometheus-client
-pytest
-pytest-benchmark
+#google-cloud-profiler
+#numpy
+prometheus-client==0.13.0
+protobuf==3.19.3
+pytest==6.2.5
+pytest-benchmark==3.4.1
 influxdb
-redis
-anytree
-apscheduler
-xmltodict
-coverage
+redis==4.1.2
+#anytree==2.8.0
+#APScheduler==3.8.1
+#xmltodict==0.12.0
+coverage==6.3
diff --git a/src/monitoring/tests/test_unitary.py b/src/monitoring/tests/test_unitary.py
index 97cdf4890..0701c5ce8 100644
--- a/src/monitoring/tests/test_unitary.py
+++ b/src/monitoring/tests/test_unitary.py
@@ -19,10 +19,9 @@ import pytest
 from typing import Tuple
 
 
-from monitoring.proto import context_pb2, kpi_sample_types_pb2
-from monitoring.proto import monitoring_pb2
 from monitoring.client.monitoring_client import MonitoringClient
-from monitoring.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, DEVICE_GRPC_GRACE_PERIOD, DEVICE_GRPC_MAX_WORKERS, DEVICE_GRPC_SERVICE_PORT, DEVICE_SERVICE_HOST
+from monitoring.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, DEVICE_GRPC_SERVICE_PORT
+from monitoring.proto import context_pb2, monitoring_pb2
 from monitoring.proto.kpi_sample_types_pb2 import KpiSampleType
 from monitoring.service import SqliteTools, InfluxTools
 from monitoring.service.MonitoringService import MonitoringService
@@ -33,7 +32,11 @@ from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBack
 from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
 from common.message_broker.MessageBroker import MessageBroker
 
-from context.Config import GRPC_SERVICE_PORT as grpc_port_context, GRPC_MAX_WORKERS as grpc_workers_context, GRPC_GRACE_PERIOD as grpc_grace_context
+from context.Config import (
+    GRPC_SERVICE_PORT as grpc_port_context,
+    GRPC_MAX_WORKERS as grpc_workers_context,
+    GRPC_GRACE_PERIOD as grpc_grace_context
+)
 from context.client.ContextClient import ContextClient
 from context.service.grpc_server.ContextService import ContextService
 from context.service.Populate import populate
@@ -104,15 +107,15 @@ def monitoring_service():
     grace_period    = GRPC_GRACE_PERIOD
 
     LOGGER.info('Initializing MonitoringService...')
-    grpc_service = MonitoringService(port=service_port, max_workers=max_workers, grace_period=grace_period)
-    server = grpc_service.start()
+    _service = MonitoringService(port=service_port, max_workers=max_workers, grace_period=grace_period)
+    _service.start()
 
     # yield the server, when test finishes, execution will resume to stop it
     LOGGER.warning('monitoring_service yielding')
-    yield server
+    yield _service
 
     LOGGER.info('Terminating MonitoringService...')
-    grpc_service.stop()
+    _service.stop()
 
 # This fixture will be requested by test cases and last during testing session.
 # The client requires the server, so client fixture has the server as dependency.
@@ -159,7 +162,7 @@ def create_kpi_request():
 
     create_kpi_request                                  = monitoring_pb2.KpiDescriptor()
     create_kpi_request.kpi_description                  = 'KPI Description Test'
-    create_kpi_request.kpi_sample_type                  = kpi_sample_types_pb2.KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED
+    create_kpi_request.kpi_sample_type                  = KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED
     create_kpi_request.device_id.device_uuid.uuid       = 'DEV1'  # pylint: disable=maybe-no-member
     create_kpi_request.service_id.service_uuid.uuid     = "SERV1"
     create_kpi_request.endpoint_id.endpoint_uuid.uuid   = "END1"
@@ -293,7 +296,7 @@ def test_sqlitedb_tools_get_kpis(sql_db):
 def test_sqlitedb_tools_delete_kpi(sql_db, create_kpi_request):
     LOGGER.warning('test_sqlitedb_tools_get_kpi begin')
 
-    response = sql_db.delete_KPI("DEV1",kpi_sample_types_pb2.KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED)
+    response = sql_db.delete_KPI("DEV1",KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED)
 
     if response == False:
         kpi_description = create_kpi_request.kpi_description
@@ -303,7 +306,7 @@ def test_sqlitedb_tools_delete_kpi(sql_db, create_kpi_request):
         kpi_service_id = create_kpi_request.service_id.service_uuid.uuid
 
         sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
-        response = sql_db.delete_KPI("DEV1", kpi_sample_types_pb2.KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED)
+        response = sql_db.delete_KPI("DEV1", KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED)
 
     assert response == True
 
diff --git a/src/opticalattackmitigator/genproto.sh b/src/opticalattackmitigator/genproto.sh
index 9f0651441..500fd1930 100755
--- a/src/opticalattackmitigator/genproto.sh
+++ b/src/opticalattackmitigator/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,14 +14,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 # building protos of services used
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
diff --git a/src/opticalattackmitigator/proto/context_pb2.py b/src/opticalattackmitigator/proto/context_pb2.py
index 68602b16f..50d501d3a 100644
--- a/src/opticalattackmitigator/proto/context_pb2.py
+++ b/src/opticalattackmitigator/proto/context_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xad\x10\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
   ,
   dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
 
@@ -55,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3703,
-  serialized_end=3809,
+  serialized_start=4310,
+  serialized_end=4416,
 )
 _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
 
@@ -101,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3812,
-  serialized_end=4009,
+  serialized_start=4419,
+  serialized_end=4616,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
 
@@ -132,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4012,
-  serialized_end=4155,
+  serialized_start=4619,
+  serialized_end=4762,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
 
@@ -168,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4158,
-  serialized_end=4287,
+  serialized_start=4765,
+  serialized_end=4894,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
 
@@ -204,12 +204,53 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4290,
-  serialized_end=4426,
+  serialized_start=4897,
+  serialized_end=5033,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
 
 ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
 _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   name='ConfigActionEnum',
   full_name='context.ConfigActionEnum',
@@ -235,8 +276,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4428,
-  serialized_end=4521,
+  serialized_start=5177,
+  serialized_end=5270,
 )
 _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
 
@@ -262,6 +303,11 @@ SERVICESTATUS_UNDEFINED = 0
 SERVICESTATUS_PLANNED = 1
 SERVICESTATUS_ACTIVE = 2
 SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
 CONFIGACTION_UNDEFINED = 0
 CONFIGACTION_SET = 1
 CONFIGACTION_DELETE = 2
@@ -1421,6 +1467,247 @@ _SERVICEEVENT = _descriptor.Descriptor(
 )
 
 
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
 _CONNECTIONID = _descriptor.Descriptor(
   name='ConnectionId',
   full_name='context.ConnectionId',
@@ -1448,8 +1735,8 @@ _CONNECTIONID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2604,
-  serialized_end=2658,
+  serialized_start=3211,
+  serialized_end=3265,
 )
 
 
@@ -1501,8 +1788,8 @@ _CONNECTION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2661,
-  serialized_end=2857,
+  serialized_start=3268,
+  serialized_end=3464,
 )
 
 
@@ -1533,8 +1820,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2859,
-  serialized_end=2924,
+  serialized_start=3466,
+  serialized_end=3531,
 )
 
 
@@ -1565,8 +1852,8 @@ _CONNECTIONLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2926,
-  serialized_end=2984,
+  serialized_start=3533,
+  serialized_end=3591,
 )
 
 
@@ -1604,8 +1891,8 @@ _CONNECTIONEVENT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2986,
-  serialized_end=3080,
+  serialized_start=3593,
+  serialized_end=3687,
 )
 
 
@@ -1650,8 +1937,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3083,
-  serialized_end=3213,
+  serialized_start=3690,
+  serialized_end=3820,
 )
 
 
@@ -1696,8 +1983,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3216,
-  serialized_end=3350,
+  serialized_start=3823,
+  serialized_end=3957,
 )
 
 
@@ -1742,8 +2029,8 @@ _CONFIGRULE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3352,
-  serialized_end=3453,
+  serialized_start=3959,
+  serialized_end=4060,
 )
 
 
@@ -1781,8 +2068,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3455,
-  serialized_end=3518,
+  serialized_start=4062,
+  serialized_end=4125,
 )
 
 
@@ -1827,8 +2114,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3520,
-  serialized_end=3614,
+  serialized_start=4127,
+  serialized_end=4221,
 )
 
 
@@ -1866,8 +2153,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3616,
-  serialized_end=3701,
+  serialized_start=4223,
+  serialized_end=4308,
 )
 
 _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
@@ -1921,6 +2208,19 @@ _SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
 _SERVICELIST.fields_by_name['services'].message_type = _SERVICE
 _SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
 _SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
 _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
 _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
 _CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
@@ -1969,6 +2269,12 @@ DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
 DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
 DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
 DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
 DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
 DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
 DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
@@ -1985,6 +2291,7 @@ DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
 DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
 DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
 DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
 DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -2205,6 +2512,48 @@ ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_messag
   })
 _sym_db.RegisterMessage(ServiceEvent)
 
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
 ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
   'DESCRIPTOR' : _CONNECTIONID,
   '__module__' : 'context_pb2'
@@ -2291,8 +2640,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=4524,
-  serialized_end=6617,
+  serialized_start=5273,
+  serialized_end=7688,
   methods=[
   _descriptor.MethodDescriptor(
     name='ListContextIds',
@@ -2594,10 +2943,70 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='ListConnectionIds',
     full_name='context.ContextService.ListConnectionIds',
-    index=30,
+    index=36,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONIDLIST,
@@ -2607,7 +3016,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='ListConnections',
     full_name='context.ContextService.ListConnections',
-    index=31,
+    index=37,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONLIST,
@@ -2617,7 +3026,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnection',
     full_name='context.ContextService.GetConnection',
-    index=32,
+    index=38,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_CONNECTION,
@@ -2627,7 +3036,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetConnection',
     full_name='context.ContextService.SetConnection',
-    index=33,
+    index=39,
     containing_service=None,
     input_type=_CONNECTION,
     output_type=_CONNECTIONID,
@@ -2637,7 +3046,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='RemoveConnection',
     full_name='context.ContextService.RemoveConnection',
-    index=34,
+    index=40,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_EMPTY,
@@ -2647,7 +3056,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnectionEvents',
     full_name='context.ContextService.GetConnectionEvents',
-    index=35,
+    index=41,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_CONNECTIONEVENT,
diff --git a/src/opticalcentralizedattackdetector/genproto.sh b/src/opticalcentralizedattackdetector/genproto.sh
index 76df9bf83..855231cce 100755
--- a/src/opticalcentralizedattackdetector/genproto.sh
+++ b/src/opticalcentralizedattackdetector/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,14 +14,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 # building protos of services used
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
diff --git a/src/opticalcentralizedattackdetector/proto/context_pb2.py b/src/opticalcentralizedattackdetector/proto/context_pb2.py
index 68602b16f..50d501d3a 100644
--- a/src/opticalcentralizedattackdetector/proto/context_pb2.py
+++ b/src/opticalcentralizedattackdetector/proto/context_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xad\x10\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
   ,
   dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
 
@@ -55,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3703,
-  serialized_end=3809,
+  serialized_start=4310,
+  serialized_end=4416,
 )
 _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
 
@@ -101,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3812,
-  serialized_end=4009,
+  serialized_start=4419,
+  serialized_end=4616,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
 
@@ -132,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4012,
-  serialized_end=4155,
+  serialized_start=4619,
+  serialized_end=4762,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
 
@@ -168,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4158,
-  serialized_end=4287,
+  serialized_start=4765,
+  serialized_end=4894,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
 
@@ -204,12 +204,53 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4290,
-  serialized_end=4426,
+  serialized_start=4897,
+  serialized_end=5033,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
 
 ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
 _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   name='ConfigActionEnum',
   full_name='context.ConfigActionEnum',
@@ -235,8 +276,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4428,
-  serialized_end=4521,
+  serialized_start=5177,
+  serialized_end=5270,
 )
 _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
 
@@ -262,6 +303,11 @@ SERVICESTATUS_UNDEFINED = 0
 SERVICESTATUS_PLANNED = 1
 SERVICESTATUS_ACTIVE = 2
 SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
 CONFIGACTION_UNDEFINED = 0
 CONFIGACTION_SET = 1
 CONFIGACTION_DELETE = 2
@@ -1421,6 +1467,247 @@ _SERVICEEVENT = _descriptor.Descriptor(
 )
 
 
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
 _CONNECTIONID = _descriptor.Descriptor(
   name='ConnectionId',
   full_name='context.ConnectionId',
@@ -1448,8 +1735,8 @@ _CONNECTIONID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2604,
-  serialized_end=2658,
+  serialized_start=3211,
+  serialized_end=3265,
 )
 
 
@@ -1501,8 +1788,8 @@ _CONNECTION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2661,
-  serialized_end=2857,
+  serialized_start=3268,
+  serialized_end=3464,
 )
 
 
@@ -1533,8 +1820,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2859,
-  serialized_end=2924,
+  serialized_start=3466,
+  serialized_end=3531,
 )
 
 
@@ -1565,8 +1852,8 @@ _CONNECTIONLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2926,
-  serialized_end=2984,
+  serialized_start=3533,
+  serialized_end=3591,
 )
 
 
@@ -1604,8 +1891,8 @@ _CONNECTIONEVENT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2986,
-  serialized_end=3080,
+  serialized_start=3593,
+  serialized_end=3687,
 )
 
 
@@ -1650,8 +1937,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3083,
-  serialized_end=3213,
+  serialized_start=3690,
+  serialized_end=3820,
 )
 
 
@@ -1696,8 +1983,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3216,
-  serialized_end=3350,
+  serialized_start=3823,
+  serialized_end=3957,
 )
 
 
@@ -1742,8 +2029,8 @@ _CONFIGRULE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3352,
-  serialized_end=3453,
+  serialized_start=3959,
+  serialized_end=4060,
 )
 
 
@@ -1781,8 +2068,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3455,
-  serialized_end=3518,
+  serialized_start=4062,
+  serialized_end=4125,
 )
 
 
@@ -1827,8 +2114,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3520,
-  serialized_end=3614,
+  serialized_start=4127,
+  serialized_end=4221,
 )
 
 
@@ -1866,8 +2153,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3616,
-  serialized_end=3701,
+  serialized_start=4223,
+  serialized_end=4308,
 )
 
 _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
@@ -1921,6 +2208,19 @@ _SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
 _SERVICELIST.fields_by_name['services'].message_type = _SERVICE
 _SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
 _SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
 _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
 _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
 _CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
@@ -1969,6 +2269,12 @@ DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
 DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
 DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
 DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
 DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
 DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
 DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
@@ -1985,6 +2291,7 @@ DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
 DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
 DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
 DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
 DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -2205,6 +2512,48 @@ ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_messag
   })
 _sym_db.RegisterMessage(ServiceEvent)
 
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
 ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
   'DESCRIPTOR' : _CONNECTIONID,
   '__module__' : 'context_pb2'
@@ -2291,8 +2640,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=4524,
-  serialized_end=6617,
+  serialized_start=5273,
+  serialized_end=7688,
   methods=[
   _descriptor.MethodDescriptor(
     name='ListContextIds',
@@ -2594,10 +2943,70 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='ListConnectionIds',
     full_name='context.ContextService.ListConnectionIds',
-    index=30,
+    index=36,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONIDLIST,
@@ -2607,7 +3016,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='ListConnections',
     full_name='context.ContextService.ListConnections',
-    index=31,
+    index=37,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONLIST,
@@ -2617,7 +3026,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnection',
     full_name='context.ContextService.GetConnection',
-    index=32,
+    index=38,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_CONNECTION,
@@ -2627,7 +3036,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetConnection',
     full_name='context.ContextService.SetConnection',
-    index=33,
+    index=39,
     containing_service=None,
     input_type=_CONNECTION,
     output_type=_CONNECTIONID,
@@ -2637,7 +3046,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='RemoveConnection',
     full_name='context.ContextService.RemoveConnection',
-    index=34,
+    index=40,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_EMPTY,
@@ -2647,7 +3056,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnectionEvents',
     full_name='context.ContextService.GetConnectionEvents',
-    index=35,
+    index=41,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_CONNECTIONEVENT,
diff --git a/src/opticalcentralizedattackdetector/proto/service_pb2.py b/src/opticalcentralizedattackdetector/proto/service_pb2.py
index 7a006915b..8e2806c76 100644
--- a/src/opticalcentralizedattackdetector/proto/service_pb2.py
+++ b/src/opticalcentralizedattackdetector/proto/service_pb2.py
@@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xfd\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12\x42\n\x11GetConnectionList\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x62\x06proto3'
+  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xb9\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
   ,
   dependencies=[context__pb2.DESCRIPTOR,])
 
@@ -38,7 +38,7 @@ _SERVICESERVICE = _descriptor.ServiceDescriptor(
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
   serialized_start=42,
-  serialized_end=295,
+  serialized_end=227,
   methods=[
   _descriptor.MethodDescriptor(
     name='CreateService',
@@ -70,16 +70,6 @@ _SERVICESERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
-  _descriptor.MethodDescriptor(
-    name='GetConnectionList',
-    full_name='service.ServiceService.GetConnectionList',
-    index=3,
-    containing_service=None,
-    input_type=context__pb2._SERVICEID,
-    output_type=context__pb2._CONNECTIONLIST,
-    serialized_options=None,
-    create_key=_descriptor._internal_create_key,
-  ),
 ])
 _sym_db.RegisterServiceDescriptor(_SERVICESERVICE)
 
diff --git a/src/service/client/ServiceClient.py b/src/service/client/ServiceClient.py
index af489c0c6..a44842768 100644
--- a/src/service/client/ServiceClient.py
+++ b/src/service/client/ServiceClient.py
@@ -14,6 +14,7 @@
 
 import grpc, logging
 from common.tools.client.RetryDecorator import retry, delay_exponential
+from common.tools.grpc.Tools import grpc_message_to_json_string
 from service.proto.context_pb2 import Empty, Service, ServiceId
 from service.proto.service_pb2_grpc import ServiceServiceStub
 
@@ -42,21 +43,21 @@ class ServiceClient:
 
     @RETRY_DECORATOR
     def CreateService(self, request : Service) -> ServiceId:
-        LOGGER.debug('CreateService request: {:s}'.format(str(request)))
+        LOGGER.debug('CreateService request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.CreateService(request)
-        LOGGER.debug('CreateService result: {:s}'.format(str(response)))
+        LOGGER.debug('CreateService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def UpdateService(self, request : Service) -> ServiceId:
-        LOGGER.debug('UpdateService request: {:s}'.format(str(request)))
+        LOGGER.debug('UpdateService request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.UpdateService(request)
-        LOGGER.debug('UpdateService result: {:s}'.format(str(response)))
+        LOGGER.debug('UpdateService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def DeleteService(self, request : ServiceId) -> Empty:
-        LOGGER.debug('DeleteService request: {:s}'.format(str(request)))
+        LOGGER.debug('DeleteService request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.DeleteService(request)
-        LOGGER.debug('DeleteService result: {:s}'.format(str(response)))
+        LOGGER.debug('DeleteService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
diff --git a/src/service/genproto.sh b/src/service/genproto.sh
index 7ea496d6f..529054968 100755
--- a/src/service/genproto.sh
+++ b/src/service/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,14 +14,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
 python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto service.proto
diff --git a/src/service/proto/context_pb2.py b/src/service/proto/context_pb2.py
index 68602b16f..50d501d3a 100644
--- a/src/service/proto/context_pb2.py
+++ b/src/service/proto/context_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xad\x10\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
   ,
   dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
 
@@ -55,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3703,
-  serialized_end=3809,
+  serialized_start=4310,
+  serialized_end=4416,
 )
 _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
 
@@ -101,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3812,
-  serialized_end=4009,
+  serialized_start=4419,
+  serialized_end=4616,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
 
@@ -132,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4012,
-  serialized_end=4155,
+  serialized_start=4619,
+  serialized_end=4762,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
 
@@ -168,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4158,
-  serialized_end=4287,
+  serialized_start=4765,
+  serialized_end=4894,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
 
@@ -204,12 +204,53 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4290,
-  serialized_end=4426,
+  serialized_start=4897,
+  serialized_end=5033,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
 
 ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
 _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   name='ConfigActionEnum',
   full_name='context.ConfigActionEnum',
@@ -235,8 +276,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4428,
-  serialized_end=4521,
+  serialized_start=5177,
+  serialized_end=5270,
 )
 _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
 
@@ -262,6 +303,11 @@ SERVICESTATUS_UNDEFINED = 0
 SERVICESTATUS_PLANNED = 1
 SERVICESTATUS_ACTIVE = 2
 SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
 CONFIGACTION_UNDEFINED = 0
 CONFIGACTION_SET = 1
 CONFIGACTION_DELETE = 2
@@ -1421,6 +1467,247 @@ _SERVICEEVENT = _descriptor.Descriptor(
 )
 
 
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
 _CONNECTIONID = _descriptor.Descriptor(
   name='ConnectionId',
   full_name='context.ConnectionId',
@@ -1448,8 +1735,8 @@ _CONNECTIONID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2604,
-  serialized_end=2658,
+  serialized_start=3211,
+  serialized_end=3265,
 )
 
 
@@ -1501,8 +1788,8 @@ _CONNECTION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2661,
-  serialized_end=2857,
+  serialized_start=3268,
+  serialized_end=3464,
 )
 
 
@@ -1533,8 +1820,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2859,
-  serialized_end=2924,
+  serialized_start=3466,
+  serialized_end=3531,
 )
 
 
@@ -1565,8 +1852,8 @@ _CONNECTIONLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2926,
-  serialized_end=2984,
+  serialized_start=3533,
+  serialized_end=3591,
 )
 
 
@@ -1604,8 +1891,8 @@ _CONNECTIONEVENT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2986,
-  serialized_end=3080,
+  serialized_start=3593,
+  serialized_end=3687,
 )
 
 
@@ -1650,8 +1937,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3083,
-  serialized_end=3213,
+  serialized_start=3690,
+  serialized_end=3820,
 )
 
 
@@ -1696,8 +1983,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3216,
-  serialized_end=3350,
+  serialized_start=3823,
+  serialized_end=3957,
 )
 
 
@@ -1742,8 +2029,8 @@ _CONFIGRULE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3352,
-  serialized_end=3453,
+  serialized_start=3959,
+  serialized_end=4060,
 )
 
 
@@ -1781,8 +2068,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3455,
-  serialized_end=3518,
+  serialized_start=4062,
+  serialized_end=4125,
 )
 
 
@@ -1827,8 +2114,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3520,
-  serialized_end=3614,
+  serialized_start=4127,
+  serialized_end=4221,
 )
 
 
@@ -1866,8 +2153,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3616,
-  serialized_end=3701,
+  serialized_start=4223,
+  serialized_end=4308,
 )
 
 _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
@@ -1921,6 +2208,19 @@ _SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
 _SERVICELIST.fields_by_name['services'].message_type = _SERVICE
 _SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
 _SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
 _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
 _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
 _CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
@@ -1969,6 +2269,12 @@ DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
 DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
 DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
 DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
 DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
 DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
 DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
@@ -1985,6 +2291,7 @@ DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
 DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
 DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
 DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
 DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -2205,6 +2512,48 @@ ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_messag
   })
 _sym_db.RegisterMessage(ServiceEvent)
 
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
 ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
   'DESCRIPTOR' : _CONNECTIONID,
   '__module__' : 'context_pb2'
@@ -2291,8 +2640,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=4524,
-  serialized_end=6617,
+  serialized_start=5273,
+  serialized_end=7688,
   methods=[
   _descriptor.MethodDescriptor(
     name='ListContextIds',
@@ -2594,10 +2943,70 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='ListConnectionIds',
     full_name='context.ContextService.ListConnectionIds',
-    index=30,
+    index=36,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONIDLIST,
@@ -2607,7 +3016,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='ListConnections',
     full_name='context.ContextService.ListConnections',
-    index=31,
+    index=37,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONLIST,
@@ -2617,7 +3026,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnection',
     full_name='context.ContextService.GetConnection',
-    index=32,
+    index=38,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_CONNECTION,
@@ -2627,7 +3036,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetConnection',
     full_name='context.ContextService.SetConnection',
-    index=33,
+    index=39,
     containing_service=None,
     input_type=_CONNECTION,
     output_type=_CONNECTIONID,
@@ -2637,7 +3046,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='RemoveConnection',
     full_name='context.ContextService.RemoveConnection',
-    index=34,
+    index=40,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_EMPTY,
@@ -2647,7 +3056,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnectionEvents',
     full_name='context.ContextService.GetConnectionEvents',
-    index=35,
+    index=41,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_CONNECTIONEVENT,
diff --git a/src/service/proto/service_pb2.py b/src/service/proto/service_pb2.py
index 7a006915b..8e2806c76 100644
--- a/src/service/proto/service_pb2.py
+++ b/src/service/proto/service_pb2.py
@@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xfd\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12\x42\n\x11GetConnectionList\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x62\x06proto3'
+  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xb9\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
   ,
   dependencies=[context__pb2.DESCRIPTOR,])
 
@@ -38,7 +38,7 @@ _SERVICESERVICE = _descriptor.ServiceDescriptor(
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
   serialized_start=42,
-  serialized_end=295,
+  serialized_end=227,
   methods=[
   _descriptor.MethodDescriptor(
     name='CreateService',
@@ -70,16 +70,6 @@ _SERVICESERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
-  _descriptor.MethodDescriptor(
-    name='GetConnectionList',
-    full_name='service.ServiceService.GetConnectionList',
-    index=3,
-    containing_service=None,
-    input_type=context__pb2._SERVICEID,
-    output_type=context__pb2._CONNECTIONLIST,
-    serialized_options=None,
-    create_key=_descriptor._internal_create_key,
-  ),
 ])
 _sym_db.RegisterServiceDescriptor(_SERVICESERVICE)
 
diff --git a/src/service/proto/service_pb2_grpc.py b/src/service/proto/service_pb2_grpc.py
index 58cd47e93..7269e1f5f 100644
--- a/src/service/proto/service_pb2_grpc.py
+++ b/src/service/proto/service_pb2_grpc.py
@@ -29,11 +29,6 @@ class ServiceServiceStub(object):
                 request_serializer=context__pb2.ServiceId.SerializeToString,
                 response_deserializer=context__pb2.Empty.FromString,
                 )
-        self.GetConnectionList = channel.unary_unary(
-                '/service.ServiceService/GetConnectionList',
-                request_serializer=context__pb2.ServiceId.SerializeToString,
-                response_deserializer=context__pb2.ConnectionList.FromString,
-                )
 
 
 class ServiceServiceServicer(object):
@@ -57,12 +52,6 @@ class ServiceServiceServicer(object):
         context.set_details('Method not implemented!')
         raise NotImplementedError('Method not implemented!')
 
-    def GetConnectionList(self, request, context):
-        """Missing associated documentation comment in .proto file."""
-        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
-        context.set_details('Method not implemented!')
-        raise NotImplementedError('Method not implemented!')
-
 
 def add_ServiceServiceServicer_to_server(servicer, server):
     rpc_method_handlers = {
@@ -81,11 +70,6 @@ def add_ServiceServiceServicer_to_server(servicer, server):
                     request_deserializer=context__pb2.ServiceId.FromString,
                     response_serializer=context__pb2.Empty.SerializeToString,
             ),
-            'GetConnectionList': grpc.unary_unary_rpc_method_handler(
-                    servicer.GetConnectionList,
-                    request_deserializer=context__pb2.ServiceId.FromString,
-                    response_serializer=context__pb2.ConnectionList.SerializeToString,
-            ),
     }
     generic_handler = grpc.method_handlers_generic_handler(
             'service.ServiceService', rpc_method_handlers)
@@ -146,20 +130,3 @@ class ServiceService(object):
             context__pb2.Empty.FromString,
             options, channel_credentials,
             insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
-
-    @staticmethod
-    def GetConnectionList(request,
-            target,
-            options=(),
-            channel_credentials=None,
-            call_credentials=None,
-            insecure=False,
-            compression=None,
-            wait_for_ready=None,
-            timeout=None,
-            metadata=None):
-        return grpc.experimental.unary_unary(request, target, '/service.ServiceService/GetConnectionList',
-            context__pb2.ServiceId.SerializeToString,
-            context__pb2.ConnectionList.FromString,
-            options, channel_credentials,
-            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py
index 2506a4206..772069932 100644
--- a/src/service/service/ServiceServiceServicerImpl.py
+++ b/src/service/service/ServiceServiceServicerImpl.py
@@ -52,6 +52,8 @@ class ServiceServiceServicerImpl(ServiceServiceServicer):
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def CreateService(self, request : Service, context : grpc.ServicerContext) -> ServiceId:
+        LOGGER.info('[CreateService] begin ; request = {:s}'.format(grpc_message_to_json_string(request)))
+
         service_id = request.service_id
         service_uuid = service_id.service_uuid.uuid
         service_context_uuid = service_id.context_id.context_uuid.uuid
diff --git a/src/slice/.gitlab-ci.yml b/src/slice/.gitlab-ci.yml
new file mode 100644
index 000000000..d62e8edad
--- /dev/null
+++ b/src/slice/.gitlab-ci.yml
@@ -0,0 +1,74 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Build, tag, and push the Docker images to the GitLab Docker registry
+build slice:
+  variables:
+    IMAGE_NAME: 'slice' # name of the microservice
+    IMAGE_NAME_TEST: 'slice-test' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: build
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+  script:
+    - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile ./src/
+    - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+  rules:
+    - changes:
+      - src/$IMAGE_NAME/**
+      - .gitlab-ci.yml
+
+# Pull, execute, and run unitary tests for the Docker image from the GitLab registry
+unit_test slice:
+  variables:
+    IMAGE_NAME: 'slice' # name of the microservice
+    IMAGE_NAME_TEST: 'slice-test' # name of the microservice
+    IMAGE_TAG: 'latest' # tag of the container image (production, development, etc)
+  stage: unit_test
+  needs:
+    - build slice
+  before_script:
+    - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - if docker network list | grep teraflowbridge; then echo "teraflowbridge is already created"; else docker network create -d bridge teraflowbridge; fi  
+  script:
+    - docker pull "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+    - docker run -d -p 4040:4040 --name $IMAGE_NAME --network=teraflowbridge "$IMAGE_NAME:$IMAGE_TAG"
+    - docker ps -a
+    - sleep 5
+    - docker ps -a
+    - docker logs $IMAGE_NAME
+    - docker exec -i $IMAGE_NAME bash -c "pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary.py"
+  after_script:
+    - docker stop $IMAGE_NAME
+    - docker rm $IMAGE_NAME
+  rules:
+    - changes:
+      - src/$IMAGE_NAME/**
+      - .gitlab-ci.yml
+
+# Deployment of the service in Kubernetes Cluster
+deploy slice:
+  stage: deploy
+  needs:
+    - build slice
+    - unit_test slice
+    - dependencies all
+    - integ_test execute
+  script:
+    - kubectl version
+    - kubectl get all
+    - kubectl apply -f "manifests/sliceservice.yaml"
+    - kubectl delete pods --selector app=sliceservice
+    - kubectl get all
diff --git a/src/slice/Config.py b/src/slice/Config.py
new file mode 100644
index 000000000..e6d770d00
--- /dev/null
+++ b/src/slice/Config.py
@@ -0,0 +1,22 @@
+import logging
+
+# General settings
+LOG_LEVEL = logging.WARNING
+
+# gRPC settings
+GRPC_SERVICE_PORT = 4040
+GRPC_MAX_WORKERS  = 10
+GRPC_GRACE_PERIOD = 60
+
+# Prometheus settings
+METRICS_PORT = 9192
+
+# Dependency micro-service connection settings
+CONTEXT_SERVICE_HOST = '127.0.0.1'
+CONTEXT_SERVICE_PORT = 1010
+
+SERVICE_SERVICE_HOST = '127.0.0.1'
+SERVICE_SERVICE_PORT = 3030
+
+INTERDOMAIN_SERVICE_HOST = '127.0.0.1'
+INTERDOMAIN_SERVICE_PORT = 10010
diff --git a/src/slice/Dockerfile b/src/slice/Dockerfile
new file mode 100644
index 000000000..d653bb217
--- /dev/null
+++ b/src/slice/Dockerfile
@@ -0,0 +1,38 @@
+FROM python:3-slim
+
+# Install dependencies
+RUN apt-get --yes --quiet --quiet update && \
+    apt-get --yes --quiet --quiet install wget g++ && \
+    rm -rf /var/lib/apt/lists/*
+
+# Set Python to show logs as they occur
+ENV PYTHONUNBUFFERED=0
+
+# Download the gRPC health probe
+RUN GRPC_HEALTH_PROBE_VERSION=v0.2.0 && \
+    wget -qO/bin/grpc_health_probe https://github.com/grpc-ecosystem/grpc-health-probe/releases/download/${GRPC_HEALTH_PROBE_VERSION}/grpc_health_probe-linux-amd64 && \
+    chmod +x /bin/grpc_health_probe
+
+# Get generic Python packages
+RUN python3 -m pip install --upgrade pip setuptools wheel pip-tools
+
+# Set working directory
+WORKDIR /var/teraflow
+
+# Create module sub-folders
+RUN mkdir -p /var/teraflow/slice
+
+# Get Python packages per module
+COPY slice/requirements.in slice/requirements.in
+RUN pip-compile --output-file=slice/requirements.txt slice/requirements.in
+RUN python3 -m pip install -r slice/requirements.in
+
+# Add files into working directory
+COPY common/. common
+COPY context/. context
+COPY interdomain/. interdomain
+COPY service/. service
+COPY slice/. slice
+
+# Start slice service
+ENTRYPOINT ["python", "-m", "slice.service"]
diff --git a/src/slice/__init__.py b/src/slice/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/slice/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/slice/client/SliceClient.py b/src/slice/client/SliceClient.py
new file mode 100644
index 000000000..5566108f8
--- /dev/null
+++ b/src/slice/client/SliceClient.py
@@ -0,0 +1,63 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from common.tools.client.RetryDecorator import retry, delay_exponential
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from slice.proto.context_pb2 import Empty, Slice, SliceId
+from slice.proto.slice_pb2_grpc import SliceServiceStub
+
+LOGGER = logging.getLogger(__name__)
+MAX_RETRIES = 15
+DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
+RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
+
+class SliceClient:
+    def __init__(self, address, port):
+        self.endpoint = '{:s}:{:s}'.format(str(address), str(port))
+        LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint))
+        self.channel = None
+        self.stub = None
+        self.connect()
+        LOGGER.debug('Channel created')
+
+    def connect(self):
+        self.channel = grpc.insecure_channel(self.endpoint)
+        self.stub = SliceServiceStub(self.channel)
+
+    def close(self):
+        if self.channel is not None: self.channel.close()
+        self.channel = None
+        self.stub = None
+
+    @RETRY_DECORATOR
+    def CreateSlice(self, request : Slice) -> SliceId:
+        LOGGER.debug('CreateSlice request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.CreateSlice(request)
+        LOGGER.debug('CreateSlice result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def UpdateSlice(self, request : Slice) -> SliceId:
+        LOGGER.debug('UpdateSlice request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.UpdateSlice(request)
+        LOGGER.debug('UpdateSlice result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def DeleteSlice(self, request : SliceId) -> Empty:
+        LOGGER.debug('DeleteSlice request: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.DeleteSlice(request)
+        LOGGER.debug('DeleteSlice result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
diff --git a/src/slice/client/__init__.py b/src/slice/client/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/slice/client/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/slice/genproto.sh b/src/slice/genproto.sh
new file mode 100755
index 000000000..e51905dd2
--- /dev/null
+++ b/src/slice/genproto.sh
@@ -0,0 +1,52 @@
+#!/bin/bash -eu
+#
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+rm -rf proto/*.py
+rm -rf proto/__pycache__
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
+
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto context.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto service.proto
+python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto slice.proto
+
+rm proto/context_pb2_grpc.py
+rm proto/kpi_sample_types_pb2_grpc.py
+rm proto/service_pb2_grpc.py
+
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/service_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/slice_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/slice_pb2_grpc.py
diff --git a/src/slice/old_code/ConstraintsChecker.py b/src/slice/old_code/ConstraintsChecker.py
new file mode 100644
index 000000000..44cf2c76d
--- /dev/null
+++ b/src/slice/old_code/ConstraintsChecker.py
@@ -0,0 +1,52 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from typing import Dict, List, Set, Tuple
+from common.Checkers import chk_string
+from common.exceptions.ServiceException import ServiceException
+from service.proto.context_pb2 import Constraint
+
+def check_constraint(
+    logger : logging.Logger, constraint_number : int, parent_name : str, constraint : Constraint,
+    add_constraints : Dict[str, Dict[str, Set[str]]]) -> Tuple[str, str]:
+
+    try:
+        constraint_type  = chk_string('constraint[#{}].constraint_type'.format(constraint_number),
+                                      constraint.constraint_type,
+                                      allow_empty=False)
+        constraint_value = chk_string('constraint[#{}].constraint_value'.format(constraint_number),
+                                      constraint.constraint_value,
+                                      allow_empty=False)
+    except Exception as e:
+        logger.exception('Invalid arguments:')
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+    if constraint_type in add_constraints:
+        msg = 'Duplicated ConstraintType({}) in {}.'
+        msg = msg.format(constraint_type, parent_name)
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+
+    add_constraints[constraint_type] = constraint_value
+    return constraint_type, constraint_value
+
+def check_constraints(logger : logging.Logger, parent_name : str, constraints):
+    add_constraints : Dict[str, str] = {}
+    constraint_tuples : List[Tuple[str, str]] = []
+    for constraint_number,constraint in enumerate(constraints):
+        _parent_name = 'Constraint(#{}) of {}'.format(constraint_number, parent_name)
+        constraint_type, constraint_value = check_constraint(
+            logger, constraint_number, _parent_name, constraint, add_constraints)
+        constraint_tuples.append((constraint_type, constraint_value))
+    return constraint_tuples
diff --git a/src/slice/old_code/SliceCheckers.py b/src/slice/old_code/SliceCheckers.py
new file mode 100644
index 000000000..660a522d0
--- /dev/null
+++ b/src/slice/old_code/SliceCheckers.py
@@ -0,0 +1,32 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc
+from common.database.api.Database import Database
+from common.database.api.context.slice.Slice import Slice
+from common.exceptions.ServiceException import ServiceException
+
+def check_slice_exists(database : Database, context_id : str, slice_id : str) -> Slice:
+    db_context = database.context(context_id).create()
+    if db_context.slices.contains(slice_id): return db_context.slice(slice_id)
+    msg = 'Context({})/Slice({}) does not exist in the database.'
+    msg = msg.format(context_id, slice_id)
+    raise ServiceException(grpc.StatusCode.NOT_FOUND, msg)
+
+def check_slice_not_exists(database : Database, context_id : str, slice_id : str):
+    db_context = database.context(context_id).create()
+    if not db_context.slices.contains(slice_id): return
+    msg = 'Context({})/Slice({}) already exists in the database.'
+    msg = msg.format(context_id, slice_id)
+    raise ServiceException(grpc.StatusCode.ALREADY_EXISTS, msg)
diff --git a/src/slice/old_code/Tools.py b/src/slice/old_code/Tools.py
new file mode 100644
index 000000000..4029c5b19
--- /dev/null
+++ b/src/slice/old_code/Tools.py
@@ -0,0 +1,213 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from typing import Dict, List, Set, Tuple
+from common.Checkers import chk_options, chk_string
+from common.database.api.Database import Database
+from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID
+from common.database.api.context.service.Service import Service
+from common.database.api.context.slice.SliceStatus import SliceStatus, slicestatus_enum_values, to_slicestatus_enum
+from common.database.api.context.topology.device.Endpoint import Endpoint
+from common.exceptions.ServiceException import ServiceException
+from common.tools.service.ConstraintsChecker import check_constraints
+from common.tools.service.EndpointIdCheckers import check_endpoint_id
+from common.tools.service.DeviceCheckers import check_device_endpoint_exists
+from common.tools.service.EnumCheckers import check_enum
+from common.tools.service.ServiceCheckers import check_service_exists
+from common.tools.service.SliceCheckers import check_slice_exists #, check_slice_not_exists
+from slice.proto.slice_pb2 import TransportSlice
+
+# For each method name, define acceptable slice statuses. Empty set means accept all.
+ACCEPTED_SLICE_STATUSES : Dict[str, Set[SliceStatus]] = {
+    'CreateUpdateSlice': set([SliceStatus.PLANNED, SliceStatus.INIT, SliceStatus.ACTIVE]),
+    'DeleteSlice': set([SliceStatus.PLANNED, SliceStatus.DEINIT]),
+}
+
+def _check_slice_exists(method_name : str, database : Database, context_id : str, slice_id : str):
+    if method_name in ['CreateUpdateSlice']:
+        # Do nothing; creation implies checking slice does not exist. However, if it exists, we can perform an update.
+        #check_slice_not_exists(database, context_id, slice_id)
+        pass
+    elif method_name in ['DeleteSlice']:
+        check_slice_exists(database, context_id, slice_id)
+    else:                                       # pragma: no cover (test requires malforming the code)
+        msg = 'Unexpected condition [_check_slice_exists(method_name={}, slice_id={})]'
+        msg = msg.format(str(method_name), str(slice_id))
+        raise ServiceException(grpc.StatusCode.UNIMPLEMENTED, msg)
+
+def _check_slice_endpoints(
+    logger : logging.Logger, database : Database, context_id : str, slice_id : str, slice_endpoints
+    ) -> List[Tuple[Endpoint, str]]:
+
+    add_topology_devices_endpoints : Dict[str, Dict[str, Set[str]]] = {}
+    db_endpoints__port_types : List[Tuple[Endpoint, str]] = []
+    for endpoint_number,slice_endpoint in enumerate(slice_endpoints):
+        parent_name = 'SliceEndpoint(#{}) of Context({})/Slice({})'
+        parent_name = parent_name.format(endpoint_number, context_id, slice_id)
+
+        ep_topology_id, ep_device_id, ep_port_id = check_endpoint_id(
+            logger, endpoint_number, parent_name, slice_endpoint.port_id.port_id, add_topology_devices_endpoints,
+            acceptable_context_ids=set([context_id]), prevent_same_device_multiple_times=False)
+
+        try:
+            ep_port_type = chk_string('endpoint[#{}].port_type'.format(endpoint_number),
+                                      slice_endpoint.port_id.port_type,
+                                      allow_empty=False)
+        except Exception as e:
+            logger.exception('Invalid arguments:')
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+        db_endpoint = check_device_endpoint_exists(
+            database, parent_name, context_id, ep_topology_id, ep_device_id, ep_port_id)
+        db_endpoints__port_types.append((db_endpoint, ep_port_type))
+    return db_endpoints__port_types
+
+def _check_services(
+    logger : logging.Logger, database : Database, parent_name : str, context_id : str, slice_service_ids
+    ) -> List[Service]:
+
+    add_context_services : Dict[str, Set[str]] = {}
+    db_services : List[Service] = []
+    for service_number,service_id in enumerate(slice_service_ids):
+        # ----- Parse attributes ---------------------------------------------------------------------------------------
+        try:
+            service_context_id = chk_string ('services[#{}].contextId.contextUuid.uuid'.format(service_number),
+                                             service_id.contextId.contextUuid.uuid,
+                                             allow_empty=True)
+            service_id         = chk_string ('services[#{}].cs_id.uuid'.format(service_number),
+                                             service_id.cs_id.uuid,
+                                             allow_empty=False)
+        except Exception as e:
+            logger.exception('Invalid arguments:')
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+        if len(service_context_id) == 0: service_context_id = context_id
+
+        add_services = add_context_services.setdefault(context_id, dict())
+        if service_id in add_services:
+            msg = 'Duplicated Context({})/Service({}) in {}.'
+            msg = msg.format(service_context_id, service_id, parent_name)
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+
+        db_service = check_service_exists(database, service_context_id, service_id)
+        db_services.append(db_service)
+        add_services.add(service_id)
+    return db_services
+
+def _check_subslices(
+    logger : logging.Logger, database : Database, parent_name : str, context_id : str, slice_subslice_ids
+    ) -> List[Slice]:
+
+    add_context_subslices : Dict[str, Set[str]] = {}
+    db_subslices : List[Slice] = []
+    for subslice_number,subslice_id in enumerate(slice_subslice_ids):
+        # ----- Parse attributes ---------------------------------------------------------------------------------------
+        try:
+            subslice_context_id = chk_string ('subSlicesId[#{}].contextId.contextUuid.uuid'.format(subslice_number),
+                                             subslice_id.contextId.contextUuid.uuid,
+                                             allow_empty=True)
+            subslice_id         = chk_string ('subSlicesId[#{}].slice_id.uuid'.format(subslice_number),
+                                             subslice_id.slice_id.uuid,
+                                             allow_empty=False)
+        except Exception as e:
+            logger.exception('Invalid arguments:')
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+        if len(subslice_context_id) == 0: subslice_context_id = context_id
+
+        add_subslices = add_context_subslices.setdefault(context_id, dict())
+        if subslice_id in add_subslices:
+            msg = 'Duplicated Context({})/Slice({}) in {}.'
+            msg = msg.format(subslice_context_id, subslice_id, parent_name)
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+
+        db_subslice = check_slice_exists(database, subslice_context_id, subslice_id)
+        db_subslices.append(db_subslice)
+        add_subslices.add(subslice_id)
+    return db_subslices
+
+def check_slice_status(method_name : str, value : str) -> SliceStatus:
+    return check_enum(
+        'SliceStatus', method_name, value, to_slicestatus_enum, ACCEPTED_SLICE_STATUSES)
+
+def check_slice_request(
+    method_name : str, request : TransportSlice, database : Database, logger : logging.Logger
+    ): # -> Tuple[str, str, str, OperationalStatus, List[Tuple[Endpoint, str]]]:
+
+    # ----- Parse attributes -------------------------------------------------------------------------------------------
+    try:
+        context_id        = chk_string ('slice.slice_id.contextId.contextUuid.uuid',
+                                        request.slice_id.contextId.contextUuid.uuid,
+                                        allow_empty=True)
+        slice_id          = chk_string ('slice.slice_id.slice_id.uuid',
+                                        request.slice_id.slice_id.uuid,
+                                        allow_empty=False)
+        status_context_id = chk_string ('slice.status.slice_id.contextId.contextUuid.uuid',
+                                        request.status.slice_id.contextId.contextUuid.uuid,
+                                        allow_empty=True)
+        status_slice_id   = chk_string ('slice.status.slice_id.slice_id.uuid',
+                                        request.status.slice_id.slice_id.uuid,
+                                        allow_empty=True)
+        slice_status      = chk_options('slice.status.status',
+                                        request.status.status,
+                                        slicestatus_enum_values())
+    except Exception as e:
+        logger.exception('Invalid arguments:')
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+    if len(context_id) == 0: context_id = DEFAULT_CONTEXT_ID
+
+    if (len(status_context_id) > 0) and (status_context_id != context_id):
+        msg = ' '.join([
+            'slice.status.slice_id.contextId.contextUuid.uuid({})',
+            'is not empty and is different than',
+            'slice.slice_id.contextId.contextUuid.uuid({}).',
+            'Optionally, leave field empty to use slice.slice_id.contextId.contextUuid.uuid({}), if set,',
+            'or, otherwise, the default Context({})'
+        ])
+        msg = msg.format(
+            status_context_id, context_id, context_id, DEFAULT_CONTEXT_ID)
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+        
+    if (len(status_slice_id) > 0) and (status_slice_id != slice_id):
+        msg = ' '.join([
+            'slice.status.slice_id.slice_id.uuid({})',
+            'is not empty and is different than',
+            'slice.slice_id.slice_id.uuid({}).',
+            'Optionally, leave field empty to use slice.slice_id.slice_id.uuid({}).',
+        ])
+        msg = msg.format(
+            status_slice_id, slice_id, slice_id)
+        raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, msg)
+
+    slice_status = check_slice_status(method_name, slice_status)
+
+    # ----- Check if slice exists in database --------------------------------------------------------------------------
+    _check_slice_exists(method_name, database, context_id, slice_id)
+
+    # ----- Parse endpoints and check if they exist in the database as device endpoints --------------------------------
+    db_endpoints__port_types = _check_slice_endpoints(logger, database, context_id, slice_id, request.endpoints)
+
+    # ----- Parse constraints ------------------------------------------------------------------------------------------
+    parent_name = 'Context({})/Slice({})'.format(context_id, slice_id)
+    constraint_tuples : List[Tuple[str, str]] = check_constraints(logger, parent_name, request.constraints)
+
+    # ----- Parse Service Ids ------------------------------------------------------------------------------------------
+    db_services = _check_services(logger, database, parent_name, context_id, request.services)
+
+    # ----- Parse SubSlice Ids -----------------------------------------------------------------------------------------
+    db_subslices = _check_subslices(logger, database, parent_name, context_id, request.subSlicesId)
+
+    return context_id, slice_id, slice_status, db_endpoints__port_types, constraint_tuples, db_services, db_subslices
diff --git a/src/slice/old_code/Tools_2.py b/src/slice/old_code/Tools_2.py
new file mode 100644
index 000000000..c29a11a06
--- /dev/null
+++ b/src/slice/old_code/Tools_2.py
@@ -0,0 +1,190 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+src/common/tools/service/DeviceCheckers.py
+    import grpc
+    from common.database.api.Database import Database
+    from common.database.api.context.topology.device.Device import Device
+    from common.database.api.context.topology.device.Endpoint import Endpoint
+    from common.exceptions.ServiceException import ServiceException
+
+    def check_device_exists(database : Database, context_id : str, topology_id : str, device_id : str) -> Device:
+        db_context = database.context(context_id).create()
+        db_topology = db_context.topology(topology_id).create()
+        if db_topology.devices.contains(device_id): return db_topology.device(device_id)
+        msg = 'Context({})/Topology({})/Device({}) does not exist in the database.'
+        msg = msg.format(context_id, topology_id, device_id)
+        raise ServiceException(grpc.StatusCode.NOT_FOUND, msg)
+
+
+src/common/tools/service/LinkCheckers.py
+    import grpc
+    from common.database.api.Database import Database
+    from common.database.api.context.topology.link.Link import Link
+    from common.exceptions.ServiceException import ServiceException
+
+    def check_link_exists(database : Database, context_id : str, topology_id : str, link_id : str) -> Link:
+        db_context = database.context(context_id).create()
+        db_topology = db_context.topology(topology_id).create()
+        if db_topology.links.contains(link_id): return db_topology.link(link_id)
+        msg = 'Context({})/Topology({})/Link({}) does not exist in the database.'
+        msg = msg.format(context_id, topology_id, link_id)
+        raise ServiceException(grpc.StatusCode.NOT_FOUND, msg)
+
+
+src/common/tools/service/ServiceCheckers.py
+    import grpc
+    from common.database.api.Database import Database
+    from common.exceptions.ServiceException import ServiceException
+
+    def check_service_exists(database : Database, context_id : str, service_id : str):
+        if not database.contexts.contains(context_id):
+            msg = 'Context({}) does not exist in the database.'
+            msg = msg.format(context_id)
+            raise ServiceException(grpc.StatusCode.NOT_FOUND, msg)
+
+        db_context = database.context(context_id)
+        if db_context.services.contains(service_id):
+            return db_context.service(service_id)
+
+        msg = 'Context({})/Service({}) does not exist in the database.'
+        msg = msg.format(context_id, service_id)
+        raise ServiceException(grpc.StatusCode.NOT_FOUND, msg)
+
+
+src/device/service/Tools.py
+    import grpc, logging
+    from typing import Dict, List, Set, Tuple
+    from common.Checkers import chk_options, chk_string
+    from common.database.api.Database import Database
+    from common.database.api.context.Constants import DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID
+    from common.database.api.context.topology.device.Endpoint import Endpoint
+    from common.database.api.context.topology.device.OperationalStatus import OperationalStatus, \
+        operationalstatus_enum_values, to_operationalstatus_enum
+    from common.exceptions.ServiceException import ServiceException
+    from common.tools.service.DeviceCheckers import check_device_endpoint_exists
+    from common.tools.service.EndpointIdCheckers import check_endpoint_id
+    from common.tools.service.EnumCheckers import check_enum
+    from common.tools.service.DeviceCheckers import check_device_exists, check_device_not_exists
+    from device.proto.context_pb2 import Device, DeviceId
+
+    # For each method name, define acceptable device operational statuses. Empty set means accept all.
+    ACCEPTED_DEVICE_OPERATIONAL_STATUSES : Dict[str, Set[OperationalStatus]] = {
+        'AddDevice': set([OperationalStatus.ENABLED, OperationalStatus.DISABLED]),
+        'UpdateDevice': set([OperationalStatus.KEEP_STATE, OperationalStatus.ENABLED, OperationalStatus.DISABLED]),
+    }
+
+    def _check_device_exists(method_name : str, database : Database, device_id : str):
+        if method_name in ['AddDevice']:
+            check_device_not_exists(database, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id)
+        elif method_name in ['UpdateDevice', 'DeleteDevice']:
+            check_device_exists(database, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id)
+        else:                                       # pragma: no cover (test requires malforming the code)
+            msg = 'Unexpected condition: _check_device_exists(method_name={}, device_id={})'
+            msg = msg.format(str(method_name), str(device_id))
+            raise ServiceException(grpc.StatusCode.UNIMPLEMENTED, msg)
+
+    def _check_device_endpoint_exists_or_get_pointer(
+        method_name : str, database : Database, parent_name : str, device_id : str, endpoint_id : str) -> Endpoint:
+
+        if method_name in ['AddDevice']:
+            db_context = database.context(DEFAULT_CONTEXT_ID)
+            db_topology = db_context.topology(DEFAULT_TOPOLOGY_ID)
+            db_device = db_topology.device(device_id)
+            return db_device.endpoint(endpoint_id)
+        elif method_name in ['UpdateDevice', 'DeleteDevice']:
+            return check_device_endpoint_exists(
+                database, parent_name, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id, endpoint_id)
+        else:                                       # pragma: no cover (test requires malforming the code)
+            msg = 'Unexpected condition: _check_device_endpoint_exists_or_get_pointer(method_name={}, ' \
+                'parent_name={}, device_id={}, endpoint_id={})'
+            msg = msg.format(str(method_name), str(parent_name), str(device_id), str(endpoint_id))
+            raise ServiceException(grpc.StatusCode.UNIMPLEMENTED, msg)
+
+    def check_device_operational_status(method_name : str, value : str) -> OperationalStatus:
+        return check_enum(
+            'OperationalStatus', method_name, value, to_operationalstatus_enum, ACCEPTED_DEVICE_OPERATIONAL_STATUSES)
+
+    def check_device_request(
+        method_name : str, request : Device, database : Database, logger : logging.Logger
+        ) -> Tuple[str, str, str, OperationalStatus, List[Tuple[Endpoint, str]]]:
+
+        # ----- Parse attributes -------------------------------------------------------------------------------------------
+        try:
+            device_id     = chk_string ('device.device_id.device_id.uuid',
+                                        request.device_id.device_id.uuid,
+                                        allow_empty=False)
+            device_type   = chk_string ('device.device_type',
+                                        request.device_type,
+                                        allow_empty=False)
+            device_config = chk_string ('device.device_config.device_config',
+                                        request.device_config.device_config,
+                                        allow_empty=True)
+            device_opstat = chk_options('device.devOperationalStatus',
+                                        request.devOperationalStatus,
+                                        operationalstatus_enum_values())
+        except Exception as e:
+            logger.exception('Invalid arguments:')
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+        device_opstat = check_device_operational_status(method_name, device_opstat)
+
+        # ----- Check if device exists in database -------------------------------------------------------------------------
+        _check_device_exists(method_name, database, device_id)
+
+        # ----- Parse endpoints and check if they exist in the database as device endpoints --------------------------------
+        add_topology_devices_endpoints : Dict[str, Dict[str, Set[str]]] = {}
+        db_endpoints__port_types : List[Tuple[Endpoint, str]] = []
+        for endpoint_number,endpoint in enumerate(request.endpointList):
+            parent_name = 'Endpoint(#{}) of Context({})/Topology({})/Device({})'
+            parent_name = parent_name.format(endpoint_number, DEFAULT_CONTEXT_ID, DEFAULT_TOPOLOGY_ID, device_id)
+
+            _, ep_device_id, ep_port_id = check_endpoint_id(
+                logger, endpoint_number, parent_name, endpoint.port_id, add_topology_devices_endpoints,
+                predefined_device_id=device_id, acceptable_device_ids=set([device_id]),
+                prevent_same_device_multiple_times=False)
+
+            try:
+                ep_port_type = chk_string('endpoint[#{}].port_type'.format(endpoint_number),
+                                        endpoint.port_type,
+                                        allow_empty=False)
+            except Exception as e:
+                logger.exception('Invalid arguments:')
+                raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+            db_endpoint = _check_device_endpoint_exists_or_get_pointer(
+                method_name, database, parent_name, ep_device_id, ep_port_id)
+            db_endpoints__port_types.append((db_endpoint, ep_port_type))
+
+        return device_id, device_type, device_config, device_opstat, db_endpoints__port_types
+
+    def check_device_id_request(
+        method_name : str, request : DeviceId, database : Database, logger : logging.Logger) -> str:
+
+        # ----- Parse attributes -------------------------------------------------------------------------------------------
+        try:
+            device_id = chk_string('device_id.device_id.uuid',
+                                request.device_id.uuid,
+                                allow_empty=False)
+        except Exception as e:
+            logger.exception('Invalid arguments:')
+            raise ServiceException(grpc.StatusCode.INVALID_ARGUMENT, str(e))
+
+        # ----- Check if device exists in database ---------------------------------------------------------------------------
+        _check_device_exists(method_name, database, device_id)
+
+        return device_id
+
+
+src/service/service/Tools.py
diff --git a/src/slice/proto/__init__.py b/src/slice/proto/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/slice/proto/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/slice/proto/context_pb2.py b/src/slice/proto/context_pb2.py
new file mode 100644
index 000000000..50d501d3a
--- /dev/null
+++ b/src/slice/proto/context_pb2.py
@@ -0,0 +1,3071 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: context.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import kpi_sample_types_pb2 as kpi__sample__types__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='context.proto',
+  package='context',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  ,
+  dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
+
+_EVENTTYPEENUM = _descriptor.EnumDescriptor(
+  name='EventTypeEnum',
+  full_name='context.EventTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_CREATE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UPDATE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_REMOVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4310,
+  serialized_end=4416,
+)
+_sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
+
+EventTypeEnum = enum_type_wrapper.EnumTypeWrapper(_EVENTTYPEENUM)
+_DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
+  name='DeviceDriverEnum',
+  full_name='context.DeviceDriverEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_OPENCONFIG', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_TRANSPORT_API', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_P4', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_IETF_NETWORK_TOPOLOGY', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_ONF_TR_352', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4419,
+  serialized_end=4616,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
+
+DeviceDriverEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEDRIVERENUM)
+_DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
+  name='DeviceOperationalStatusEnum',
+  full_name='context.DeviceOperationalStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_DISABLED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_ENABLED', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4619,
+  serialized_end=4762,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
+
+DeviceOperationalStatusEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEOPERATIONALSTATUSENUM)
+_SERVICETYPEENUM = _descriptor.EnumDescriptor(
+  name='ServiceTypeEnum',
+  full_name='context.ServiceTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L3NM', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L2NM', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_TAPI_CONNECTIVITY_SERVICE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4765,
+  serialized_end=4894,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
+
+ServiceTypeEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPEENUM)
+_SERVICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='ServiceStatusEnum',
+  full_name='context.ServiceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_ACTIVE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PENDING_REMOVAL', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4897,
+  serialized_end=5033,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
+
+ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
+_CONFIGACTIONENUM = _descriptor.EnumDescriptor(
+  name='ConfigActionEnum',
+  full_name='context.ConfigActionEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_SET', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_DELETE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5177,
+  serialized_end=5270,
+)
+_sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
+
+ConfigActionEnum = enum_type_wrapper.EnumTypeWrapper(_CONFIGACTIONENUM)
+EVENTTYPE_UNDEFINED = 0
+EVENTTYPE_CREATE = 1
+EVENTTYPE_UPDATE = 2
+EVENTTYPE_REMOVE = 3
+DEVICEDRIVER_UNDEFINED = 0
+DEVICEDRIVER_OPENCONFIG = 1
+DEVICEDRIVER_TRANSPORT_API = 2
+DEVICEDRIVER_P4 = 3
+DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4
+DEVICEDRIVER_ONF_TR_352 = 5
+DEVICEOPERATIONALSTATUS_UNDEFINED = 0
+DEVICEOPERATIONALSTATUS_DISABLED = 1
+DEVICEOPERATIONALSTATUS_ENABLED = 2
+SERVICETYPE_UNKNOWN = 0
+SERVICETYPE_L3NM = 1
+SERVICETYPE_L2NM = 2
+SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3
+SERVICESTATUS_UNDEFINED = 0
+SERVICESTATUS_PLANNED = 1
+SERVICESTATUS_ACTIVE = 2
+SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
+CONFIGACTION_UNDEFINED = 0
+CONFIGACTION_SET = 1
+CONFIGACTION_DELETE = 2
+
+
+
+_EMPTY = _descriptor.Descriptor(
+  name='Empty',
+  full_name='context.Empty',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=50,
+  serialized_end=57,
+)
+
+
+_UUID = _descriptor.Descriptor(
+  name='Uuid',
+  full_name='context.Uuid',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='uuid', full_name='context.Uuid.uuid', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=59,
+  serialized_end=79,
+)
+
+
+_EVENT = _descriptor.Descriptor(
+  name='Event',
+  full_name='context.Event',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='context.Event.timestamp', index=0,
+      number=1, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='event_type', full_name='context.Event.event_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=81,
+  serialized_end=151,
+)
+
+
+_CONTEXTID = _descriptor.Descriptor(
+  name='ContextId',
+  full_name='context.ContextId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_uuid', full_name='context.ContextId.context_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=153,
+  serialized_end=201,
+)
+
+
+_CONTEXT = _descriptor.Descriptor(
+  name='Context',
+  full_name='context.Context',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.Context.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.Context.topology_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.Context.service_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='controller', full_name='context.Context.controller', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=204,
+  serialized_end=386,
+)
+
+
+_CONTEXTIDLIST = _descriptor.Descriptor(
+  name='ContextIdList',
+  full_name='context.ContextIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_ids', full_name='context.ContextIdList.context_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=388,
+  serialized_end=444,
+)
+
+
+_CONTEXTLIST = _descriptor.Descriptor(
+  name='ContextList',
+  full_name='context.ContextList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contexts', full_name='context.ContextList.contexts', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=446,
+  serialized_end=495,
+)
+
+
+_CONTEXTEVENT = _descriptor.Descriptor(
+  name='ContextEvent',
+  full_name='context.ContextEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ContextEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ContextEvent.context_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=497,
+  serialized_end=582,
+)
+
+
+_TOPOLOGYID = _descriptor.Descriptor(
+  name='TopologyId',
+  full_name='context.TopologyId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TopologyId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_uuid', full_name='context.TopologyId.topology_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=584,
+  serialized_end=674,
+)
+
+
+_TOPOLOGY = _descriptor.Descriptor(
+  name='Topology',
+  full_name='context.Topology',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.Topology.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.Topology.device_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.Topology.link_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=676,
+  serialized_end=802,
+)
+
+
+_TOPOLOGYIDLIST = _descriptor.Descriptor(
+  name='TopologyIdList',
+  full_name='context.TopologyIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.TopologyIdList.topology_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=804,
+  serialized_end=863,
+)
+
+
+_TOPOLOGYLIST = _descriptor.Descriptor(
+  name='TopologyList',
+  full_name='context.TopologyList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topologies', full_name='context.TopologyList.topologies', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=865,
+  serialized_end=918,
+)
+
+
+_TOPOLOGYEVENT = _descriptor.Descriptor(
+  name='TopologyEvent',
+  full_name='context.TopologyEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.TopologyEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.TopologyEvent.topology_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=920,
+  serialized_end=1008,
+)
+
+
+_DEVICEID = _descriptor.Descriptor(
+  name='DeviceId',
+  full_name='context.DeviceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_uuid', full_name='context.DeviceId.device_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1010,
+  serialized_end=1056,
+)
+
+
+_DEVICE = _descriptor.Descriptor(
+  name='Device',
+  full_name='context.Device',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.Device.device_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_type', full_name='context.Device.device_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_config', full_name='context.Device.device_config', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_operational_status', full_name='context.Device.device_operational_status', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_drivers', full_name='context.Device.device_drivers', index=4,
+      number=5, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_endpoints', full_name='context.Device.device_endpoints', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1059,
+  serialized_end=1341,
+)
+
+
+_DEVICECONFIG = _descriptor.Descriptor(
+  name='DeviceConfig',
+  full_name='context.DeviceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.DeviceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1343,
+  serialized_end=1400,
+)
+
+
+_DEVICEIDLIST = _descriptor.Descriptor(
+  name='DeviceIdList',
+  full_name='context.DeviceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.DeviceIdList.device_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1402,
+  serialized_end=1455,
+)
+
+
+_DEVICELIST = _descriptor.Descriptor(
+  name='DeviceList',
+  full_name='context.DeviceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='devices', full_name='context.DeviceList.devices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1457,
+  serialized_end=1503,
+)
+
+
+_DEVICEEVENT = _descriptor.Descriptor(
+  name='DeviceEvent',
+  full_name='context.DeviceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.DeviceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.DeviceEvent.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1505,
+  serialized_end=1587,
+)
+
+
+_LINKID = _descriptor.Descriptor(
+  name='LinkId',
+  full_name='context.LinkId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_uuid', full_name='context.LinkId.link_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1589,
+  serialized_end=1631,
+)
+
+
+_LINK = _descriptor.Descriptor(
+  name='Link',
+  full_name='context.Link',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.Link.link_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_endpoint_ids', full_name='context.Link.link_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1633,
+  serialized_end=1721,
+)
+
+
+_LINKIDLIST = _descriptor.Descriptor(
+  name='LinkIdList',
+  full_name='context.LinkIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.LinkIdList.link_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1723,
+  serialized_end=1770,
+)
+
+
+_LINKLIST = _descriptor.Descriptor(
+  name='LinkList',
+  full_name='context.LinkList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='links', full_name='context.LinkList.links', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1772,
+  serialized_end=1812,
+)
+
+
+_LINKEVENT = _descriptor.Descriptor(
+  name='LinkEvent',
+  full_name='context.LinkEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.LinkEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.LinkEvent.link_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1814,
+  serialized_end=1890,
+)
+
+
+_SERVICEID = _descriptor.Descriptor(
+  name='ServiceId',
+  full_name='context.ServiceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ServiceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_uuid', full_name='context.ServiceId.service_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1892,
+  serialized_end=1980,
+)
+
+
+_SERVICE = _descriptor.Descriptor(
+  name='Service',
+  full_name='context.Service',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Service.service_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_type', full_name='context.Service.service_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_endpoint_ids', full_name='context.Service.service_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_constraints', full_name='context.Service.service_constraints', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.Service.service_status', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_config', full_name='context.Service.service_config', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1983,
+  serialized_end=2277,
+)
+
+
+_SERVICESTATUS = _descriptor.Descriptor(
+  name='ServiceStatus',
+  full_name='context.ServiceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.ServiceStatus.service_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2279,
+  serialized_end=2346,
+)
+
+
+_SERVICECONFIG = _descriptor.Descriptor(
+  name='ServiceConfig',
+  full_name='context.ServiceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.ServiceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2348,
+  serialized_end=2406,
+)
+
+
+_SERVICEIDLIST = _descriptor.Descriptor(
+  name='ServiceIdList',
+  full_name='context.ServiceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.ServiceIdList.service_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2408,
+  serialized_end=2464,
+)
+
+
+_SERVICELIST = _descriptor.Descriptor(
+  name='ServiceList',
+  full_name='context.ServiceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='services', full_name='context.ServiceList.services', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2466,
+  serialized_end=2515,
+)
+
+
+_SERVICEEVENT = _descriptor.Descriptor(
+  name='ServiceEvent',
+  full_name='context.ServiceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ServiceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.ServiceEvent.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2517,
+  serialized_end=2602,
+)
+
+
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
+_CONNECTIONID = _descriptor.Descriptor(
+  name='ConnectionId',
+  full_name='context.ConnectionId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_uuid', full_name='context.ConnectionId.connection_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3211,
+  serialized_end=3265,
+)
+
+
+_CONNECTION = _descriptor.Descriptor(
+  name='Connection',
+  full_name='context.Connection',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.Connection.connection_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Connection.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='path_hops_endpoint_ids', full_name='context.Connection.path_hops_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='sub_service_ids', full_name='context.Connection.sub_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3268,
+  serialized_end=3464,
+)
+
+
+_CONNECTIONIDLIST = _descriptor.Descriptor(
+  name='ConnectionIdList',
+  full_name='context.ConnectionIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_ids', full_name='context.ConnectionIdList.connection_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3466,
+  serialized_end=3531,
+)
+
+
+_CONNECTIONLIST = _descriptor.Descriptor(
+  name='ConnectionList',
+  full_name='context.ConnectionList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connections', full_name='context.ConnectionList.connections', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3533,
+  serialized_end=3591,
+)
+
+
+_CONNECTIONEVENT = _descriptor.Descriptor(
+  name='ConnectionEvent',
+  full_name='context.ConnectionEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ConnectionEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.ConnectionEvent.connection_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3593,
+  serialized_end=3687,
+)
+
+
+_ENDPOINTID = _descriptor.Descriptor(
+  name='EndPointId',
+  full_name='context.EndPointId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.EndPointId.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.EndPointId.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_uuid', full_name='context.EndPointId.endpoint_uuid', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3690,
+  serialized_end=3820,
+)
+
+
+_ENDPOINT = _descriptor.Descriptor(
+  name='EndPoint',
+  full_name='context.EndPoint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='endpoint_id', full_name='context.EndPoint.endpoint_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_type', full_name='context.EndPoint.endpoint_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='kpi_sample_types', full_name='context.EndPoint.kpi_sample_types', index=2,
+      number=3, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3823,
+  serialized_end=3957,
+)
+
+
+_CONFIGRULE = _descriptor.Descriptor(
+  name='ConfigRule',
+  full_name='context.ConfigRule',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='action', full_name='context.ConfigRule.action', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_key', full_name='context.ConfigRule.resource_key', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_value', full_name='context.ConfigRule.resource_value', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3959,
+  serialized_end=4060,
+)
+
+
+_CONSTRAINT = _descriptor.Descriptor(
+  name='Constraint',
+  full_name='context.Constraint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='constraint_type', full_name='context.Constraint.constraint_type', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='constraint_value', full_name='context.Constraint.constraint_value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4062,
+  serialized_end=4125,
+)
+
+
+_TERAFLOWCONTROLLER = _descriptor.Descriptor(
+  name='TeraFlowController',
+  full_name='context.TeraFlowController',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TeraFlowController.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='ip_address', full_name='context.TeraFlowController.ip_address', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='port', full_name='context.TeraFlowController.port', index=2,
+      number=3, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4127,
+  serialized_end=4221,
+)
+
+
+_AUTHENTICATIONRESULT = _descriptor.Descriptor(
+  name='AuthenticationResult',
+  full_name='context.AuthenticationResult',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.AuthenticationResult.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='authenticated', full_name='context.AuthenticationResult.authenticated', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4223,
+  serialized_end=4308,
+)
+
+_EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
+_CONTEXTID.fields_by_name['context_uuid'].message_type = _UUID
+_CONTEXT.fields_by_name['context_id'].message_type = _CONTEXTID
+_CONTEXT.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_CONTEXT.fields_by_name['service_ids'].message_type = _SERVICEID
+_CONTEXT.fields_by_name['controller'].message_type = _TERAFLOWCONTROLLER
+_CONTEXTIDLIST.fields_by_name['context_ids'].message_type = _CONTEXTID
+_CONTEXTLIST.fields_by_name['contexts'].message_type = _CONTEXT
+_CONTEXTEVENT.fields_by_name['event'].message_type = _EVENT
+_CONTEXTEVENT.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['topology_uuid'].message_type = _UUID
+_TOPOLOGY.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_TOPOLOGY.fields_by_name['device_ids'].message_type = _DEVICEID
+_TOPOLOGY.fields_by_name['link_ids'].message_type = _LINKID
+_TOPOLOGYIDLIST.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_TOPOLOGYLIST.fields_by_name['topologies'].message_type = _TOPOLOGY
+_TOPOLOGYEVENT.fields_by_name['event'].message_type = _EVENT
+_TOPOLOGYEVENT.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_DEVICEID.fields_by_name['device_uuid'].message_type = _UUID
+_DEVICE.fields_by_name['device_id'].message_type = _DEVICEID
+_DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG
+_DEVICE.fields_by_name['device_operational_status'].enum_type = _DEVICEOPERATIONALSTATUSENUM
+_DEVICE.fields_by_name['device_drivers'].enum_type = _DEVICEDRIVERENUM
+_DEVICE.fields_by_name['device_endpoints'].message_type = _ENDPOINT
+_DEVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_DEVICEIDLIST.fields_by_name['device_ids'].message_type = _DEVICEID
+_DEVICELIST.fields_by_name['devices'].message_type = _DEVICE
+_DEVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_DEVICEEVENT.fields_by_name['device_id'].message_type = _DEVICEID
+_LINKID.fields_by_name['link_uuid'].message_type = _UUID
+_LINK.fields_by_name['link_id'].message_type = _LINKID
+_LINK.fields_by_name['link_endpoint_ids'].message_type = _ENDPOINTID
+_LINKIDLIST.fields_by_name['link_ids'].message_type = _LINKID
+_LINKLIST.fields_by_name['links'].message_type = _LINK
+_LINKEVENT.fields_by_name['event'].message_type = _EVENT
+_LINKEVENT.fields_by_name['link_id'].message_type = _LINKID
+_SERVICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SERVICEID.fields_by_name['service_uuid'].message_type = _UUID
+_SERVICE.fields_by_name['service_id'].message_type = _SERVICEID
+_SERVICE.fields_by_name['service_type'].enum_type = _SERVICETYPEENUM
+_SERVICE.fields_by_name['service_endpoint_ids'].message_type = _ENDPOINTID
+_SERVICE.fields_by_name['service_constraints'].message_type = _CONSTRAINT
+_SERVICE.fields_by_name['service_status'].message_type = _SERVICESTATUS
+_SERVICE.fields_by_name['service_config'].message_type = _SERVICECONFIG
+_SERVICESTATUS.fields_by_name['service_status'].enum_type = _SERVICESTATUSENUM
+_SERVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
+_SERVICELIST.fields_by_name['services'].message_type = _SERVICE
+_SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
+_CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
+_CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
+_CONNECTION.fields_by_name['path_hops_endpoint_ids'].message_type = _ENDPOINTID
+_CONNECTION.fields_by_name['sub_service_ids'].message_type = _SERVICEID
+_CONNECTIONIDLIST.fields_by_name['connection_ids'].message_type = _CONNECTIONID
+_CONNECTIONLIST.fields_by_name['connections'].message_type = _CONNECTION
+_CONNECTIONEVENT.fields_by_name['event'].message_type = _EVENT
+_CONNECTIONEVENT.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_ENDPOINTID.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID
+_ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID
+_ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID
+_ENDPOINT.fields_by_name['kpi_sample_types'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE
+_CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM
+_TERAFLOWCONTROLLER.fields_by_name['context_id'].message_type = _CONTEXTID
+_AUTHENTICATIONRESULT.fields_by_name['context_id'].message_type = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
+DESCRIPTOR.message_types_by_name['Uuid'] = _UUID
+DESCRIPTOR.message_types_by_name['Event'] = _EVENT
+DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT
+DESCRIPTOR.message_types_by_name['ContextIdList'] = _CONTEXTIDLIST
+DESCRIPTOR.message_types_by_name['ContextList'] = _CONTEXTLIST
+DESCRIPTOR.message_types_by_name['ContextEvent'] = _CONTEXTEVENT
+DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID
+DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY
+DESCRIPTOR.message_types_by_name['TopologyIdList'] = _TOPOLOGYIDLIST
+DESCRIPTOR.message_types_by_name['TopologyList'] = _TOPOLOGYLIST
+DESCRIPTOR.message_types_by_name['TopologyEvent'] = _TOPOLOGYEVENT
+DESCRIPTOR.message_types_by_name['DeviceId'] = _DEVICEID
+DESCRIPTOR.message_types_by_name['Device'] = _DEVICE
+DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG
+DESCRIPTOR.message_types_by_name['DeviceIdList'] = _DEVICEIDLIST
+DESCRIPTOR.message_types_by_name['DeviceList'] = _DEVICELIST
+DESCRIPTOR.message_types_by_name['DeviceEvent'] = _DEVICEEVENT
+DESCRIPTOR.message_types_by_name['LinkId'] = _LINKID
+DESCRIPTOR.message_types_by_name['Link'] = _LINK
+DESCRIPTOR.message_types_by_name['LinkIdList'] = _LINKIDLIST
+DESCRIPTOR.message_types_by_name['LinkList'] = _LINKLIST
+DESCRIPTOR.message_types_by_name['LinkEvent'] = _LINKEVENT
+DESCRIPTOR.message_types_by_name['ServiceId'] = _SERVICEID
+DESCRIPTOR.message_types_by_name['Service'] = _SERVICE
+DESCRIPTOR.message_types_by_name['ServiceStatus'] = _SERVICESTATUS
+DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
+DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
+DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
+DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
+DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
+DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
+DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
+DESCRIPTOR.message_types_by_name['ConnectionList'] = _CONNECTIONLIST
+DESCRIPTOR.message_types_by_name['ConnectionEvent'] = _CONNECTIONEVENT
+DESCRIPTOR.message_types_by_name['EndPointId'] = _ENDPOINTID
+DESCRIPTOR.message_types_by_name['EndPoint'] = _ENDPOINT
+DESCRIPTOR.message_types_by_name['ConfigRule'] = _CONFIGRULE
+DESCRIPTOR.message_types_by_name['Constraint'] = _CONSTRAINT
+DESCRIPTOR.message_types_by_name['TeraFlowController'] = _TERAFLOWCONTROLLER
+DESCRIPTOR.message_types_by_name['AuthenticationResult'] = _AUTHENTICATIONRESULT
+DESCRIPTOR.enum_types_by_name['EventTypeEnum'] = _EVENTTYPEENUM
+DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
+DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
+DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
+DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
+  'DESCRIPTOR' : _EMPTY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Empty)
+  })
+_sym_db.RegisterMessage(Empty)
+
+Uuid = _reflection.GeneratedProtocolMessageType('Uuid', (_message.Message,), {
+  'DESCRIPTOR' : _UUID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Uuid)
+  })
+_sym_db.RegisterMessage(Uuid)
+
+Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), {
+  'DESCRIPTOR' : _EVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Event)
+  })
+_sym_db.RegisterMessage(Event)
+
+ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextId)
+  })
+_sym_db.RegisterMessage(ContextId)
+
+Context = _reflection.GeneratedProtocolMessageType('Context', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Context)
+  })
+_sym_db.RegisterMessage(Context)
+
+ContextIdList = _reflection.GeneratedProtocolMessageType('ContextIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextIdList)
+  })
+_sym_db.RegisterMessage(ContextIdList)
+
+ContextList = _reflection.GeneratedProtocolMessageType('ContextList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextList)
+  })
+_sym_db.RegisterMessage(ContextList)
+
+ContextEvent = _reflection.GeneratedProtocolMessageType('ContextEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextEvent)
+  })
+_sym_db.RegisterMessage(ContextEvent)
+
+TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyId)
+  })
+_sym_db.RegisterMessage(TopologyId)
+
+Topology = _reflection.GeneratedProtocolMessageType('Topology', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Topology)
+  })
+_sym_db.RegisterMessage(Topology)
+
+TopologyIdList = _reflection.GeneratedProtocolMessageType('TopologyIdList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyIdList)
+  })
+_sym_db.RegisterMessage(TopologyIdList)
+
+TopologyList = _reflection.GeneratedProtocolMessageType('TopologyList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyList)
+  })
+_sym_db.RegisterMessage(TopologyList)
+
+TopologyEvent = _reflection.GeneratedProtocolMessageType('TopologyEvent', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyEvent)
+  })
+_sym_db.RegisterMessage(TopologyEvent)
+
+DeviceId = _reflection.GeneratedProtocolMessageType('DeviceId', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceId)
+  })
+_sym_db.RegisterMessage(DeviceId)
+
+Device = _reflection.GeneratedProtocolMessageType('Device', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Device)
+  })
+_sym_db.RegisterMessage(Device)
+
+DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceConfig)
+  })
+_sym_db.RegisterMessage(DeviceConfig)
+
+DeviceIdList = _reflection.GeneratedProtocolMessageType('DeviceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceIdList)
+  })
+_sym_db.RegisterMessage(DeviceIdList)
+
+DeviceList = _reflection.GeneratedProtocolMessageType('DeviceList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceList)
+  })
+_sym_db.RegisterMessage(DeviceList)
+
+DeviceEvent = _reflection.GeneratedProtocolMessageType('DeviceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceEvent)
+  })
+_sym_db.RegisterMessage(DeviceEvent)
+
+LinkId = _reflection.GeneratedProtocolMessageType('LinkId', (_message.Message,), {
+  'DESCRIPTOR' : _LINKID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkId)
+  })
+_sym_db.RegisterMessage(LinkId)
+
+Link = _reflection.GeneratedProtocolMessageType('Link', (_message.Message,), {
+  'DESCRIPTOR' : _LINK,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Link)
+  })
+_sym_db.RegisterMessage(Link)
+
+LinkIdList = _reflection.GeneratedProtocolMessageType('LinkIdList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkIdList)
+  })
+_sym_db.RegisterMessage(LinkIdList)
+
+LinkList = _reflection.GeneratedProtocolMessageType('LinkList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkList)
+  })
+_sym_db.RegisterMessage(LinkList)
+
+LinkEvent = _reflection.GeneratedProtocolMessageType('LinkEvent', (_message.Message,), {
+  'DESCRIPTOR' : _LINKEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkEvent)
+  })
+_sym_db.RegisterMessage(LinkEvent)
+
+ServiceId = _reflection.GeneratedProtocolMessageType('ServiceId', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceId)
+  })
+_sym_db.RegisterMessage(ServiceId)
+
+Service = _reflection.GeneratedProtocolMessageType('Service', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Service)
+  })
+_sym_db.RegisterMessage(Service)
+
+ServiceStatus = _reflection.GeneratedProtocolMessageType('ServiceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceStatus)
+  })
+_sym_db.RegisterMessage(ServiceStatus)
+
+ServiceConfig = _reflection.GeneratedProtocolMessageType('ServiceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceConfig)
+  })
+_sym_db.RegisterMessage(ServiceConfig)
+
+ServiceIdList = _reflection.GeneratedProtocolMessageType('ServiceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceIdList)
+  })
+_sym_db.RegisterMessage(ServiceIdList)
+
+ServiceList = _reflection.GeneratedProtocolMessageType('ServiceList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceList)
+  })
+_sym_db.RegisterMessage(ServiceList)
+
+ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceEvent)
+  })
+_sym_db.RegisterMessage(ServiceEvent)
+
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
+ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionId)
+  })
+_sym_db.RegisterMessage(ConnectionId)
+
+Connection = _reflection.GeneratedProtocolMessageType('Connection', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTION,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Connection)
+  })
+_sym_db.RegisterMessage(Connection)
+
+ConnectionIdList = _reflection.GeneratedProtocolMessageType('ConnectionIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionIdList)
+  })
+_sym_db.RegisterMessage(ConnectionIdList)
+
+ConnectionList = _reflection.GeneratedProtocolMessageType('ConnectionList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionList)
+  })
+_sym_db.RegisterMessage(ConnectionList)
+
+ConnectionEvent = _reflection.GeneratedProtocolMessageType('ConnectionEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionEvent)
+  })
+_sym_db.RegisterMessage(ConnectionEvent)
+
+EndPointId = _reflection.GeneratedProtocolMessageType('EndPointId', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPointId)
+  })
+_sym_db.RegisterMessage(EndPointId)
+
+EndPoint = _reflection.GeneratedProtocolMessageType('EndPoint', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPoint)
+  })
+_sym_db.RegisterMessage(EndPoint)
+
+ConfigRule = _reflection.GeneratedProtocolMessageType('ConfigRule', (_message.Message,), {
+  'DESCRIPTOR' : _CONFIGRULE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConfigRule)
+  })
+_sym_db.RegisterMessage(ConfigRule)
+
+Constraint = _reflection.GeneratedProtocolMessageType('Constraint', (_message.Message,), {
+  'DESCRIPTOR' : _CONSTRAINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Constraint)
+  })
+_sym_db.RegisterMessage(Constraint)
+
+TeraFlowController = _reflection.GeneratedProtocolMessageType('TeraFlowController', (_message.Message,), {
+  'DESCRIPTOR' : _TERAFLOWCONTROLLER,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TeraFlowController)
+  })
+_sym_db.RegisterMessage(TeraFlowController)
+
+AuthenticationResult = _reflection.GeneratedProtocolMessageType('AuthenticationResult', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHENTICATIONRESULT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.AuthenticationResult)
+  })
+_sym_db.RegisterMessage(AuthenticationResult)
+
+
+
+_CONTEXTSERVICE = _descriptor.ServiceDescriptor(
+  name='ContextService',
+  full_name='context.ContextService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=5273,
+  serialized_end=7688,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='ListContextIds',
+    full_name='context.ContextService.ListContextIds',
+    index=0,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListContexts',
+    full_name='context.ContextService.ListContexts',
+    index=1,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContext',
+    full_name='context.ContextService.GetContext',
+    index=2,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_CONTEXT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetContext',
+    full_name='context.ContextService.SetContext',
+    index=3,
+    containing_service=None,
+    input_type=_CONTEXT,
+    output_type=_CONTEXTID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveContext',
+    full_name='context.ContextService.RemoveContext',
+    index=4,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContextEvents',
+    full_name='context.ContextService.GetContextEvents',
+    index=5,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologyIds',
+    full_name='context.ContextService.ListTopologyIds',
+    index=6,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologies',
+    full_name='context.ContextService.ListTopologies',
+    index=7,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopology',
+    full_name='context.ContextService.GetTopology',
+    index=8,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_TOPOLOGY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetTopology',
+    full_name='context.ContextService.SetTopology',
+    index=9,
+    containing_service=None,
+    input_type=_TOPOLOGY,
+    output_type=_TOPOLOGYID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveTopology',
+    full_name='context.ContextService.RemoveTopology',
+    index=10,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopologyEvents',
+    full_name='context.ContextService.GetTopologyEvents',
+    index=11,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_TOPOLOGYEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDeviceIds',
+    full_name='context.ContextService.ListDeviceIds',
+    index=12,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDevices',
+    full_name='context.ContextService.ListDevices',
+    index=13,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDevice',
+    full_name='context.ContextService.GetDevice',
+    index=14,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_DEVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetDevice',
+    full_name='context.ContextService.SetDevice',
+    index=15,
+    containing_service=None,
+    input_type=_DEVICE,
+    output_type=_DEVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveDevice',
+    full_name='context.ContextService.RemoveDevice',
+    index=16,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDeviceEvents',
+    full_name='context.ContextService.GetDeviceEvents',
+    index=17,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinkIds',
+    full_name='context.ContextService.ListLinkIds',
+    index=18,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinks',
+    full_name='context.ContextService.ListLinks',
+    index=19,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLink',
+    full_name='context.ContextService.GetLink',
+    index=20,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_LINK,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetLink',
+    full_name='context.ContextService.SetLink',
+    index=21,
+    containing_service=None,
+    input_type=_LINK,
+    output_type=_LINKID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveLink',
+    full_name='context.ContextService.RemoveLink',
+    index=22,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLinkEvents',
+    full_name='context.ContextService.GetLinkEvents',
+    index=23,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServiceIds',
+    full_name='context.ContextService.ListServiceIds',
+    index=24,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServices',
+    full_name='context.ContextService.ListServices',
+    index=25,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetService',
+    full_name='context.ContextService.GetService',
+    index=26,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_SERVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetService',
+    full_name='context.ContextService.SetService',
+    index=27,
+    containing_service=None,
+    input_type=_SERVICE,
+    output_type=_SERVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveService',
+    full_name='context.ContextService.RemoveService',
+    index=28,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetServiceEvents',
+    full_name='context.ContextService.GetServiceEvents',
+    index=29,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SERVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnectionIds',
+    full_name='context.ContextService.ListConnectionIds',
+    index=36,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnections',
+    full_name='context.ContextService.ListConnections',
+    index=37,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnection',
+    full_name='context.ContextService.GetConnection',
+    index=38,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_CONNECTION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetConnection',
+    full_name='context.ContextService.SetConnection',
+    index=39,
+    containing_service=None,
+    input_type=_CONNECTION,
+    output_type=_CONNECTIONID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveConnection',
+    full_name='context.ContextService.RemoveConnection',
+    index=40,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnectionEvents',
+    full_name='context.ContextService.GetConnectionEvents',
+    index=41,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONNECTIONEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CONTEXTSERVICE)
+
+DESCRIPTOR.services_by_name['ContextService'] = _CONTEXTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/slice/proto/kpi_sample_types_pb2.py b/src/slice/proto/kpi_sample_types_pb2.py
new file mode 100644
index 000000000..ea7fd2f82
--- /dev/null
+++ b/src/slice/proto/kpi_sample_types_pb2.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: kpi_sample_types.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='kpi_sample_types.proto',
+  package='kpi_sample_types',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*\xbe\x01\n\rKpiSampleType\x12\x19\n\x15KPISAMPLETYPE_UNKNOWN\x10\x00\x12%\n!KPISAMPLETYPE_PACKETS_TRANSMITTED\x10\x65\x12\"\n\x1eKPISAMPLETYPE_PACKETS_RECEIVED\x10\x66\x12$\n\x1fKPISAMPLETYPE_BYTES_TRANSMITTED\x10\xc9\x01\x12!\n\x1cKPISAMPLETYPE_BYTES_RECEIVED\x10\xca\x01\x62\x06proto3'
+)
+
+_KPISAMPLETYPE = _descriptor.EnumDescriptor(
+  name='KpiSampleType',
+  full_name='kpi_sample_types.KpiSampleType',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_TRANSMITTED', index=1, number=101,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_RECEIVED', index=2, number=102,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_TRANSMITTED', index=3, number=201,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_RECEIVED', index=4, number=202,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=45,
+  serialized_end=235,
+)
+_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE)
+
+KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE)
+KPISAMPLETYPE_UNKNOWN = 0
+KPISAMPLETYPE_PACKETS_TRANSMITTED = 101
+KPISAMPLETYPE_PACKETS_RECEIVED = 102
+KPISAMPLETYPE_BYTES_TRANSMITTED = 201
+KPISAMPLETYPE_BYTES_RECEIVED = 202
+
+
+DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/slice/proto/service_pb2.py b/src/slice/proto/service_pb2.py
new file mode 100644
index 000000000..8e2806c76
--- /dev/null
+++ b/src/slice/proto/service_pb2.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: service.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import context_pb2 as context__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='service.proto',
+  package='service',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xb9\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
+  ,
+  dependencies=[context__pb2.DESCRIPTOR,])
+
+
+
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+_SERVICESERVICE = _descriptor.ServiceDescriptor(
+  name='ServiceService',
+  full_name='service.ServiceService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=42,
+  serialized_end=227,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='CreateService',
+    full_name='service.ServiceService.CreateService',
+    index=0,
+    containing_service=None,
+    input_type=context__pb2._SERVICE,
+    output_type=context__pb2._SERVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='UpdateService',
+    full_name='service.ServiceService.UpdateService',
+    index=1,
+    containing_service=None,
+    input_type=context__pb2._SERVICE,
+    output_type=context__pb2._SERVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='DeleteService',
+    full_name='service.ServiceService.DeleteService',
+    index=2,
+    containing_service=None,
+    input_type=context__pb2._SERVICEID,
+    output_type=context__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_SERVICESERVICE)
+
+DESCRIPTOR.services_by_name['ServiceService'] = _SERVICESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/slice/proto/slice_pb2.py b/src/slice/proto/slice_pb2.py
new file mode 100644
index 000000000..1e2a5f31c
--- /dev/null
+++ b/src/slice/proto/slice_pb2.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: slice.proto
+"""Generated protocol buffer code."""
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import context_pb2 as context__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='slice.proto',
+  package='slice',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x0bslice.proto\x12\x05slice\x1a\rcontext.proto2\xa7\x01\n\x0cSliceService\x12\x31\n\x0b\x43reateSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bUpdateSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0b\x44\x65leteSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
+  ,
+  dependencies=[context__pb2.DESCRIPTOR,])
+
+
+
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+
+_SLICESERVICE = _descriptor.ServiceDescriptor(
+  name='SliceService',
+  full_name='slice.SliceService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=38,
+  serialized_end=205,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='CreateSlice',
+    full_name='slice.SliceService.CreateSlice',
+    index=0,
+    containing_service=None,
+    input_type=context__pb2._SLICE,
+    output_type=context__pb2._SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='UpdateSlice',
+    full_name='slice.SliceService.UpdateSlice',
+    index=1,
+    containing_service=None,
+    input_type=context__pb2._SLICE,
+    output_type=context__pb2._SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='DeleteSlice',
+    full_name='slice.SliceService.DeleteSlice',
+    index=2,
+    containing_service=None,
+    input_type=context__pb2._SLICEID,
+    output_type=context__pb2._EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_SLICESERVICE)
+
+DESCRIPTOR.services_by_name['SliceService'] = _SLICESERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/slice/proto/slice_pb2_grpc.py b/src/slice/proto/slice_pb2_grpc.py
new file mode 100644
index 000000000..abc2d884f
--- /dev/null
+++ b/src/slice/proto/slice_pb2_grpc.py
@@ -0,0 +1,132 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+from . import context_pb2 as context__pb2
+
+
+class SliceServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.CreateSlice = channel.unary_unary(
+                '/slice.SliceService/CreateSlice',
+                request_serializer=context__pb2.Slice.SerializeToString,
+                response_deserializer=context__pb2.SliceId.FromString,
+                )
+        self.UpdateSlice = channel.unary_unary(
+                '/slice.SliceService/UpdateSlice',
+                request_serializer=context__pb2.Slice.SerializeToString,
+                response_deserializer=context__pb2.SliceId.FromString,
+                )
+        self.DeleteSlice = channel.unary_unary(
+                '/slice.SliceService/DeleteSlice',
+                request_serializer=context__pb2.SliceId.SerializeToString,
+                response_deserializer=context__pb2.Empty.FromString,
+                )
+
+
+class SliceServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def CreateSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def UpdateSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def DeleteSlice(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_SliceServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'CreateSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.CreateSlice,
+                    request_deserializer=context__pb2.Slice.FromString,
+                    response_serializer=context__pb2.SliceId.SerializeToString,
+            ),
+            'UpdateSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.UpdateSlice,
+                    request_deserializer=context__pb2.Slice.FromString,
+                    response_serializer=context__pb2.SliceId.SerializeToString,
+            ),
+            'DeleteSlice': grpc.unary_unary_rpc_method_handler(
+                    servicer.DeleteSlice,
+                    request_deserializer=context__pb2.SliceId.FromString,
+                    response_serializer=context__pb2.Empty.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'slice.SliceService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class SliceService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def CreateSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/slice.SliceService/CreateSlice',
+            context__pb2.Slice.SerializeToString,
+            context__pb2.SliceId.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def UpdateSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/slice.SliceService/UpdateSlice',
+            context__pb2.Slice.SerializeToString,
+            context__pb2.SliceId.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def DeleteSlice(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/slice.SliceService/DeleteSlice',
+            context__pb2.SliceId.SerializeToString,
+            context__pb2.Empty.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/slice/requirements.in b/src/slice/requirements.in
new file mode 100644
index 000000000..162ecde82
--- /dev/null
+++ b/src/slice/requirements.in
@@ -0,0 +1,6 @@
+grpcio==1.43.0
+grpcio-health-checking==1.43.0
+prometheus-client==0.13.0
+protobuf==3.19.3
+pytest==6.2.5
+pytest-benchmark==3.4.1
diff --git a/src/slice/service/SliceService.py b/src/slice/service/SliceService.py
new file mode 100644
index 000000000..a7ad26946
--- /dev/null
+++ b/src/slice/service/SliceService.py
@@ -0,0 +1,76 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from concurrent import futures
+from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
+from grpc_health.v1.health_pb2 import HealthCheckResponse
+from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
+from context.client.ContextClient import ContextClient
+from interdomain.client.InterdomainClient import InterdomainClient
+from service.client.ServiceClient import ServiceClient
+from slice.proto.slice_pb2_grpc import add_SliceServiceServicer_to_server
+from slice.service.SliceServiceServicerImpl import SliceServiceServicerImpl
+from slice.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+
+BIND_ADDRESS = '0.0.0.0'
+LOGGER = logging.getLogger(__name__)
+
+class SliceService:
+    def __init__(
+        self, context_client : ContextClient, interdomain_client : InterdomainClient, service_client : ServiceClient,
+        address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD):
+
+        self.context_client = context_client
+        self.interdomain_client = interdomain_client
+        self.service_client = service_client
+        self.address = address
+        self.port = port
+        self.endpoint = None
+        self.max_workers = max_workers
+        self.grace_period = grace_period
+        self.slice_servicer = None
+        self.health_servicer = None
+        self.pool = None
+        self.server = None
+
+    def start(self):
+        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
+        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
+            str(self.endpoint), str(self.max_workers)))
+
+        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
+        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
+
+        self.slice_servicer = SliceServiceServicerImpl(
+            self.context_client, self.interdomain_client, self.service_client)
+        add_SliceServiceServicer_to_server(self.slice_servicer, self.server)
+
+        self.health_servicer = HealthServicer(
+            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
+        add_HealthServicer_to_server(self.health_servicer, self.server)
+
+        port = self.server.add_insecure_port(self.endpoint)
+        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
+        LOGGER.info('Listening on {:s}...'.format(str(self.endpoint)))
+        self.server.start()
+        self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
+
+        LOGGER.debug('Service started')
+
+    def stop(self):
+        LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
+        self.health_servicer.enter_graceful_shutdown()
+        self.server.stop(self.grace_period)
+        LOGGER.debug('Service stopped')
diff --git a/src/slice/service/SliceServiceServicerImpl.py b/src/slice/service/SliceServiceServicerImpl.py
new file mode 100644
index 000000000..bd26d1943
--- /dev/null
+++ b/src/slice/service/SliceServiceServicerImpl.py
@@ -0,0 +1,134 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, json, logging
+from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import (
+    ConfigActionEnum, Empty, Service, ServiceStatusEnum, ServiceTypeEnum, Slice, SliceId, SliceStatusEnum)
+from interdomain.client.InterdomainClient import InterdomainClient
+from service.client.ServiceClient import ServiceClient
+from slice.proto.slice_pb2_grpc import SliceServiceServicer
+
+LOGGER = logging.getLogger(__name__)
+
+SERVICE_NAME = 'Slice'
+METHOD_NAMES = ['CreateSlice', 'UpdateSlice', 'DeleteSlice']
+METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
+
+class SliceServiceServicerImpl(SliceServiceServicer):
+    def __init__(
+        self, context_client : ContextClient, interdomain_client : InterdomainClient, service_client : ServiceClient
+    ):
+        LOGGER.debug('Creating Servicer...')
+        self.context_client = context_client
+        self.interdomain_client = interdomain_client
+        self.service_client = service_client
+        LOGGER.debug('Servicer Created')
+
+    def create_update(self, request : Slice) -> SliceId:
+        slice_id = self.context_client.SetSlice(request)
+        if len(request.slice_endpoint_ids) != 2: return slice_id
+
+        domains = set()
+        for slice_endpoint_id in request.slice_endpoint_ids:
+            device_uuid = slice_endpoint_id.device_id.device_uuid.uuid
+            domains.add(device_uuid.split('@')[1])
+
+        is_multi_domain = len(domains) == 2
+        if is_multi_domain:
+            slice_id = self.interdomain_client.RequestSlice(request)
+        else:
+            # pylint: disable=no-member
+            service_request = Service()
+            service_request.service_id.context_id.context_uuid.uuid = request.slice_id.context_id.context_uuid.uuid
+            service_request.service_id.service_uuid.uuid = request.slice_id.slice_uuid.uuid
+            service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
+            service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
+
+            service_reply = self.service_client.CreateService(service_request)
+            if service_reply != service_request.service_id: # pylint: disable=no-member
+                raise Exception('Service creation failed. Wrong Service Id was returned')
+
+            config_rule = service_request.service_config.config_rules.add()
+            config_rule.action = ConfigActionEnum.CONFIGACTION_SET
+            config_rule.resource_key = '/settings'
+            config_rule.resource_value = json.dumps(
+                {'mtu': 1512, 'address_families': ['IPV4'], 'bgp_as': 65000, 'bgp_route_target': '65000:333'},
+                sort_keys=True)
+
+            for slice_endpoint_id in request.slice_endpoint_ids:
+                device_uuid = slice_endpoint_id.device_id.device_uuid.uuid
+                endpoint_uuid = slice_endpoint_id.endpoint_uuid.uuid
+
+                endpoint_id = service_request.service_endpoint_ids.add()
+                endpoint_id.device_id.device_uuid.uuid = device_uuid
+                endpoint_id.endpoint_uuid.uuid = endpoint_uuid
+
+                config_rule = service_request.service_config.config_rules.add()
+                config_rule.action = ConfigActionEnum.CONFIGACTION_SET
+                config_rule.resource_key = '/device[{:s}]/endpoint[{:s}]/settings'.format(device_uuid, endpoint_uuid)
+                config_rule.resource_value = json.dumps(
+                    {'router_id': '0.0.0.0', 'route_distinguisher': '0:0', 'sub_interface_index': 0, 'vlan_id': 0,
+                     'address_ip': '0.0.0.0', 'address_prefix': 0},
+                    sort_keys=True)
+
+            service_reply = self.service_client.UpdateService(service_request)
+            if service_reply != service_request.service_id: # pylint: disable=no-member
+                raise Exception('Service update failed. Wrong Service Id was returned')
+
+            reply = Slice()
+            reply.CopyFrom(request)
+            slice_service_id = reply.slice_service_ids.add()
+            slice_service_id.CopyFrom(service_reply)
+            self.context_client.SetSlice(reply)
+            slice_id = reply.slice_id
+
+        slice_ = self.context_client.GetSlice(slice_id)
+        slice_active = Slice()
+        slice_active.CopyFrom(slice_)
+        slice_active.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_ACTIVE
+        self.context_client.SetSlice(slice_active)
+        return slice_id
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def CreateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
+        #try:
+        #    slice_ = self.context_client.GetSlice(request.slice_id)
+        #    slice_id = slice_.slice_id
+        #except grpc.RpcError:
+        #    slice_id = self.context_client.SetSlice(request)
+        #return slice_id
+        return self.create_update(request)
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def UpdateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
+        #slice_id = self.context_client.SetSlice(request)
+        #if len(request.slice_endpoint_ids) != 2: return slice_id
+        #
+        #domains = set()
+        #for slice_endpoint_id in request.slice_endpoint_ids:
+        #    device_uuid = slice_endpoint_id.device_id.device_uuid.uuid
+        #    domains.add(device_uuid.split('@')[0])
+        #
+        #is_multi_domain = len(domains) == 2
+        #if is_multi_domain:
+        #    return self.interdomain_client.LookUpSlice(request)
+        #else:
+        #    raise NotImplementedError('Slice should create local services for single domain slice')
+        return self.create_update(request)
+
+    @safe_and_metered_rpc_method(METRICS, LOGGER)
+    def DeleteSlice(self, request : SliceId, context : grpc.ServicerContext) -> Empty:
+        return Empty()
diff --git a/src/slice/service/__init__.py b/src/slice/service/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/slice/service/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/slice/service/__main__.py b/src/slice/service/__main__.py
new file mode 100644
index 000000000..76bb5fa34
--- /dev/null
+++ b/src/slice/service/__main__.py
@@ -0,0 +1,101 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, signal, sys, threading
+from prometheus_client import start_http_server
+from common.Settings import get_setting, wait_for_environment_variables
+from context.client.ContextClient import ContextClient
+from interdomain.client.InterdomainClient import InterdomainClient
+from service.client.ServiceClient import ServiceClient
+from slice.Config import (
+    CONTEXT_SERVICE_HOST, CONTEXT_SERVICE_PORT, GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD,
+    INTERDOMAIN_SERVICE_HOST, INTERDOMAIN_SERVICE_PORT, LOG_LEVEL, METRICS_PORT, SERVICE_SERVICE_HOST,
+    SERVICE_SERVICE_PORT)
+from .SliceService import SliceService
+
+terminate = threading.Event()
+LOGGER : logging.Logger = None
+
+def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
+    LOGGER.warning('Terminate signal received')
+    terminate.set()
+
+def main():
+    global LOGGER # pylint: disable=global-statement
+
+    grpc_service_port        = get_setting('SLICESERVICE_SERVICE_PORT_GRPC',       default=GRPC_SERVICE_PORT       )
+    max_workers              = get_setting('MAX_WORKERS',                          default=GRPC_MAX_WORKERS        )
+    grace_period             = get_setting('GRACE_PERIOD',                         default=GRPC_GRACE_PERIOD       )
+    log_level                = get_setting('LOG_LEVEL',                            default=LOG_LEVEL               )
+    metrics_port             = get_setting('METRICS_PORT',                         default=METRICS_PORT            )
+
+    logging.basicConfig(level=log_level)
+    LOGGER = logging.getLogger(__name__)
+
+    wait_for_environment_variables([
+        'CONTEXTSERVICE_SERVICE_HOST', 'CONTEXTSERVICE_SERVICE_PORT_GRPC',
+        'INTERDOMAINSERVICE_SERVICE_HOST', 'INTERDOMAINSERVICE_SERVICE_PORT_GRPC',
+        'SERVICESERVICE_SERVICE_HOST', 'SERVICESERVICE_SERVICE_PORT_GRPC',
+    ])
+
+    context_service_host     = get_setting('CONTEXTSERVICE_SERVICE_HOST',          default=CONTEXT_SERVICE_HOST    )
+    context_service_port     = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC',     default=CONTEXT_SERVICE_PORT    )
+    interdomain_service_host = get_setting('INTERDOMAINSERVICE_SERVICE_HOST',      default=INTERDOMAIN_SERVICE_HOST)
+    interdomain_service_port = get_setting('INTERDOMAINSERVICE_SERVICE_PORT_GRPC', default=INTERDOMAIN_SERVICE_PORT)
+    service_service_host     = get_setting('SERVICESERVICE_SERVICE_HOST',          default=SERVICE_SERVICE_HOST    )
+    service_service_port     = get_setting('SERVICESERVICE_SERVICE_PORT_GRPC',     default=SERVICE_SERVICE_PORT    )
+
+    signal.signal(signal.SIGINT,  signal_handler)
+    signal.signal(signal.SIGTERM, signal_handler)
+
+    LOGGER.info('Starting...')
+
+    # Start metrics server
+    start_http_server(metrics_port)
+
+    # Initialize Context Client
+    if context_service_host is None or context_service_port is None:
+        raise Exception('Wrong address({:s}):port({:s}) of Context component'.format(
+            str(context_service_host), str(context_service_port)))
+    context_client = ContextClient(context_service_host, context_service_port)
+
+    # Initialize Interdomain Client
+    if interdomain_service_host is None or interdomain_service_port is None:
+        raise Exception('Wrong address({:s}):port({:s}) of Interdomain component'.format(
+            str(interdomain_service_host), str(interdomain_service_port)))
+    interdomain_client = InterdomainClient(interdomain_service_host, interdomain_service_port)
+
+    # Initialize Service Client
+    if service_service_host is None or service_service_port is None:
+        raise Exception('Wrong address({:s}):port({:s}) of Service component'.format(
+            str(service_service_host), str(service_service_port)))
+    service_client = ServiceClient(service_service_host, service_service_port)
+
+    # Starting slice service
+    grpc_service = SliceService(
+        context_client, interdomain_client, service_client, port=grpc_service_port, max_workers=max_workers,
+        grace_period=grace_period)
+    grpc_service.start()
+
+    # Wait for Ctrl+C or termination signal
+    while not terminate.wait(timeout=0.1): pass
+
+    LOGGER.info('Terminating...')
+    grpc_service.stop()
+
+    LOGGER.info('Bye')
+    return 0
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/src/slice/tests/__init__.py b/src/slice/tests/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/slice/tests/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/slice/tests/test_unitary.py b/src/slice/tests/test_unitary.py
new file mode 100644
index 000000000..fb58b5153
--- /dev/null
+++ b/src/slice/tests/test_unitary.py
@@ -0,0 +1,51 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy, grpc, logging, pytest
+from common.database.Factory import get_database, DatabaseEngineEnum
+from slice.client.SliceClient import SliceClient
+from slice.proto.slice_pb2 import TransportSlice
+from slice.service.SliceService import SliceService
+from slice.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+
+port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+@pytest.fixture(scope='session')
+def slice_database():
+    _database = get_database(engine=DatabaseEngineEnum.INMEMORY)
+    return _database
+
+@pytest.fixture(scope='session')
+def slice_service(slice_database):
+    _service = SliceService(
+        slice_database, port=port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD)
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def slice_client(slice_service):
+    _client = SliceClient(address='127.0.0.1', port=port)
+    yield _client
+    _client.close()
+
+#def test_add_device_wrong_attributes(slice_client : SliceClient):
+#    # should fail with slice uuid is empty
+#    with pytest.raises(grpc._channel._InactiveRpcError) as e:
+#        slice_client.CreateUpdateSlice(TransportSlice())
+#    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+#    assert e.value.details() == 'slice.slice_id.slice_id.uuid() string is empty.'
diff --git a/src/tests/.gitlab-ci.yml b/src/tests/.gitlab-ci.yml
index e663b09ec..6fcac6480 100644
--- a/src/tests/.gitlab-ci.yml
+++ b/src/tests/.gitlab-ci.yml
@@ -14,4 +14,5 @@
 
 # include the individual .gitlab-ci.yml of each integration test
 include:
-  - local: '/src/tests/ofc22_bootstrap_monitor_l3vpn/.gitlab-ci.yml'
+  - local: '/src/tests/ofc22/.gitlab-ci.yml'
+  - local: '/src/tests/oeccpsc22/.gitlab-ci.yml'
diff --git a/src/tests/oeccpsc22/README.md b/src/tests/oeccpsc22/README.md
new file mode 100644
index 000000000..42e0228a5
--- /dev/null
+++ b/src/tests/oeccpsc22/README.md
@@ -0,0 +1,8 @@
+# OECC/PSC'22 Paper - Interdomain slices
+This functional test reproduces the experiment in paper "... paper title ..." presented at OECC/PSC'22 conference
+[OECC/PSC'22](... demo link ...).
+
+## Functional test folder
+This functional test can be found in folder `./src/tests/oeccpsc22/`. A convenience alias `./oeccpsc22/` pointing to that folder has been defined.
+
+# TO BE WRITTEN
diff --git a/src/tests/oeccpsc22/__init__.py b/src/tests/oeccpsc22/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/tests/oeccpsc22/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/tests/oeccpsc22/deploy_in_kubernetes.sh b/src/tests/oeccpsc22/deploy_in_kubernetes.sh
new file mode 100755
index 000000000..426e07e13
--- /dev/null
+++ b/src/tests/oeccpsc22/deploy_in_kubernetes.sh
@@ -0,0 +1,159 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+# OECC/PSC 22 deployment settings
+export REGISTRY_IMAGE=""
+export COMPONENTS="context device monitoring service slice interdomain compute" # webui
+export IMAGE_TAG="oeccpsc22"
+export K8S_HOSTNAME="kubernetes-master"
+#export GRAFANA_PASSWORD="admin123+"
+
+# Constants
+GITLAB_REPO_URL="registry.gitlab.com/teraflow-h2020/controller"
+TMP_FOLDER="./tmp"
+
+# Create a tmp folder for files modified during the deployment
+TMP_MANIFESTS_FOLDER="$TMP_FOLDER/manifests"
+mkdir -p $TMP_MANIFESTS_FOLDER
+TMP_LOGS_FOLDER="$TMP_FOLDER/logs"
+mkdir -p $TMP_LOGS_FOLDER
+
+export K8S_NAMESPACE_1="oeccpsc22-1"
+export K8S_NAMESPACE_2="oeccpsc22-2"
+
+export EXTRA_MANIFESTS_1="./oeccpsc22/expose_services_teraflow_1.yaml"
+export EXTRA_MANIFESTS_2="./oeccpsc22/expose_services_teraflow_2.yaml"
+
+echo "Deleting and Creating new namespaces..."
+kubectl delete namespace $K8S_NAMESPACE_1 $K8S_NAMESPACE_2
+kubectl create namespace $K8S_NAMESPACE_1
+kubectl create namespace $K8S_NAMESPACE_2
+printf "\n"
+
+echo "Creating secrets for InfluxDB..."
+#TODO: make sure to change this when having a production deployment
+kubectl create secret generic influxdb-secrets --namespace=$K8S_NAMESPACE_1 --from-literal=INFLUXDB_DB="monitoring" --from-literal=INFLUXDB_ADMIN_USER="teraflow" --from-literal=INFLUXDB_ADMIN_PASSWORD="teraflow" --from-literal=INFLUXDB_HTTP_AUTH_ENABLED="True"
+kubectl create secret generic monitoring-secrets --namespace=$K8S_NAMESPACE_1 --from-literal=INFLUXDB_DATABASE="monitoring" --from-literal=INFLUXDB_USER="teraflow" --from-literal=INFLUXDB_PASSWORD="teraflow" --from-literal=INFLUXDB_HOSTNAME="localhost"
+
+kubectl create secret generic influxdb-secrets --namespace=$K8S_NAMESPACE_2 --from-literal=INFLUXDB_DB="monitoring" --from-literal=INFLUXDB_ADMIN_USER="teraflow" --from-literal=INFLUXDB_ADMIN_PASSWORD="teraflow" --from-literal=INFLUXDB_HTTP_AUTH_ENABLED="True"
+kubectl create secret generic monitoring-secrets --namespace=$K8S_NAMESPACE_2 --from-literal=INFLUXDB_DATABASE="monitoring" --from-literal=INFLUXDB_USER="teraflow" --from-literal=INFLUXDB_PASSWORD="teraflow" --from-literal=INFLUXDB_HOSTNAME="localhost"
+printf "\n"
+
+echo "Pulling/Updating Docker images..."
+docker pull redis:6.2
+docker pull influxdb:1.8
+docker pull grafana/grafana:8.2.6
+printf "\n"
+
+echo "Deploying components..."
+for COMPONENT in $COMPONENTS; do
+    echo "Processing '$COMPONENT' component..."
+    IMAGE_NAME="$COMPONENT:$IMAGE_TAG"
+    IMAGE_URL="$REGISTRY_IMAGE/$IMAGE_NAME"
+
+    echo "  Building Docker image..."
+    BUILD_LOG="$TMP_LOGS_FOLDER/build_${COMPONENT}.log"
+
+    if [ "$COMPONENT" == "automation" ] || [ "$COMPONENT" == "policy" ]; then
+        docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile ./src/"$COMPONENT"/ > "$BUILD_LOG"
+    else 
+        docker build -t "$IMAGE_NAME" -f ./src/"$COMPONENT"/Dockerfile ./src/ > "$BUILD_LOG"
+    fi
+
+    if [ -n "$REGISTRY_IMAGE" ]; then
+        echo "Pushing Docker image to '$REGISTRY_IMAGE'..."
+
+        TAG_LOG="$TMP_LOGS_FOLDER/tag_${COMPONENT}.log"
+        docker tag "$IMAGE_NAME" "$IMAGE_URL" > "$TAG_LOG"
+
+        PUSH_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}.log"
+        docker push "$IMAGE_URL" > "$PUSH_LOG"
+    fi
+
+    echo "  Adapting '$COMPONENT' manifest file..."
+    MANIFEST="$TMP_MANIFESTS_FOLDER/${COMPONENT}service.yaml"
+    cp ./manifests/"${COMPONENT}"service.yaml "$MANIFEST"
+    VERSION=$(grep -i "${GITLAB_REPO_URL}/${COMPONENT}:" "$MANIFEST" | cut -d ":" -f3)
+
+    if [ -n "$REGISTRY_IMAGE" ]; then
+
+        sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_URL#g" "$MANIFEST"
+        sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Always#g" "$MANIFEST"
+   
+    else
+        sed -E -i "s#image: $GITLAB_REPO_URL/$COMPONENT:${VERSION}#image: $IMAGE_NAME#g" "$MANIFEST"
+        sed -E -i "s#imagePullPolicy: .*#imagePullPolicy: Never#g" "$MANIFEST"        
+    fi
+
+    echo "  Deploying '$COMPONENT' component to Kubernetes $K8S_NAMESPACE_1..."
+    DEPLOY_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}_1.log"
+    kubectl --namespace $K8S_NAMESPACE_1 apply -f "$MANIFEST" > "$DEPLOY_LOG"
+    kubectl --namespace $K8S_NAMESPACE_1 scale deployment --replicas=0 ${COMPONENT}service >> "$DEPLOY_LOG"
+    kubectl --namespace $K8S_NAMESPACE_1 scale deployment --replicas=1 ${COMPONENT}service >> "$DEPLOY_LOG"
+
+    echo "  Deploying '$COMPONENT' component to Kubernetes $K8S_NAMESPACE_2..."
+    DEPLOY_LOG="$TMP_LOGS_FOLDER/push_${COMPONENT}_2.log"
+    kubectl --namespace $K8S_NAMESPACE_2 apply -f "$MANIFEST" > "$DEPLOY_LOG"
+    kubectl --namespace $K8S_NAMESPACE_2 scale deployment --replicas=0 ${COMPONENT}service >> "$DEPLOY_LOG"
+    kubectl --namespace $K8S_NAMESPACE_2 scale deployment --replicas=1 ${COMPONENT}service >> "$DEPLOY_LOG"
+
+    printf "\n"
+done
+
+echo "Deploying extra manifests to Kubernetes $K8S_NAMESPACE_1..."
+for EXTRA_MANIFEST in $EXTRA_MANIFESTS_1; do
+    echo "Processing manifest '$EXTRA_MANIFEST'..."
+    kubectl --namespace $K8S_NAMESPACE_1 apply -f $EXTRA_MANIFEST
+    printf "\n"
+done
+
+echo "Deploying extra manifests to Kubernetes $K8S_NAMESPACE_2..."
+for EXTRA_MANIFEST in $EXTRA_MANIFESTS_2; do
+    echo "Processing manifest '$EXTRA_MANIFEST'..."
+    kubectl --namespace $K8S_NAMESPACE_2 apply -f $EXTRA_MANIFEST
+    printf "\n"
+done
+
+# By now, leave this control here. Some component dependencies are not well handled
+for COMPONENT in $COMPONENTS; do
+    echo "Waiting for '$COMPONENT' component in Kubernetes $K8S_NAMESPACE_1..."
+    kubectl wait --namespace $K8S_NAMESPACE_1 --for='condition=available' --timeout=300s deployment/${COMPONENT}service
+    printf "\n"
+
+    echo "Waiting for '$COMPONENT' component in Kubernetes $K8S_NAMESPACE_2..."
+    kubectl wait --namespace $K8S_NAMESPACE_2 --for='condition=available' --timeout=300s deployment/${COMPONENT}service
+    printf "\n"
+done
+
+if [[ "$COMPONENTS" == *"webui"* ]]; then
+    echo "Configuring WebUI DataStores and Dashboards..."
+    ./configure_dashboards.sh
+    printf "\n\n"
+fi
+
+echo "Removing dangling docker images..."
+docker images --filter="dangling=true" --quiet | xargs -r docker rmi
+printf "\n"
+
+echo "Reporting Deployment in Kubernetes $K8S_NAMESPACE_1..."
+kubectl --namespace $K8S_NAMESPACE_1 get all
+printf "\n"
+
+echo "Reporting Deployment in Kubernetes $K8S_NAMESPACE_2..."
+kubectl --namespace $K8S_NAMESPACE_2 get all
+printf "\n"
+
+echo "Done!"
diff --git a/src/tests/oeccpsc22/dump_logs.sh b/src/tests/oeccpsc22/dump_logs.sh
new file mode 100755
index 000000000..196002a5f
--- /dev/null
+++ b/src/tests/oeccpsc22/dump_logs.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+mkdir -p tmp/exec_logs/
+
+kubectl --namespace oeccpsc22-1 logs deployment/computeservice -c server > tmp/exec_logs/d1_compute.log
+kubectl --namespace oeccpsc22-1 logs deployment/contextservice -c server > tmp/exec_logs/d1_context.log
+kubectl --namespace oeccpsc22-1 logs deployment/deviceservice -c server > tmp/exec_logs/d1_device.log
+kubectl --namespace oeccpsc22-1 logs deployment/interdomainservice -c server > tmp/exec_logs/d1_interdomain.log
+kubectl --namespace oeccpsc22-1 logs deployment/monitoringservice -c server > tmp/exec_logs/d1_monitoring.log
+kubectl --namespace oeccpsc22-1 logs deployment/serviceservice -c server > tmp/exec_logs/d1_service.log
+kubectl --namespace oeccpsc22-1 logs deployment/sliceservice -c server > tmp/exec_logs/d1_slice.log
+
+kubectl --namespace oeccpsc22-2 logs deployment/computeservice -c server > tmp/exec_logs/d2_compute.log
+kubectl --namespace oeccpsc22-2 logs deployment/contextservice -c server > tmp/exec_logs/d2_context.log
+kubectl --namespace oeccpsc22-2 logs deployment/deviceservice -c server > tmp/exec_logs/d2_device.log
+kubectl --namespace oeccpsc22-2 logs deployment/interdomainservice -c server > tmp/exec_logs/d2_interdomain.log
+kubectl --namespace oeccpsc22-2 logs deployment/monitoringservice -c server > tmp/exec_logs/d2_monitoring.log
+kubectl --namespace oeccpsc22-2 logs deployment/serviceservice -c server > tmp/exec_logs/d2_service.log
+kubectl --namespace oeccpsc22-2 logs deployment/sliceservice -c server > tmp/exec_logs/d2_slice.log
diff --git a/src/tests/oeccpsc22/expose_services_teraflow_1.yaml b/src/tests/oeccpsc22/expose_services_teraflow_1.yaml
new file mode 100644
index 000000000..f2b8de0b1
--- /dev/null
+++ b/src/tests/oeccpsc22/expose_services_teraflow_1.yaml
@@ -0,0 +1,106 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: remote-teraflow
+spec:
+  type: ExternalName
+  externalName: interdomainservice.oeccpsc22-2.svc.cluster.local
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 10010
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: contextservice-public
+  labels:
+    app: contextservice
+spec:
+  type: NodePort
+  selector:
+    app: contextservice
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 1010
+    targetPort: 1010
+    nodePort: 30111
+  - name: rest
+    protocol: TCP
+    port: 8080
+    targetPort: 8080
+    nodePort: 30001
+  - name: redis
+    protocol: TCP
+    port: 6379
+    targetPort: 6379
+    nodePort: 30631
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: deviceservice-public
+  labels:
+    app: deviceservice
+spec:
+  type: NodePort
+  selector:
+    app: deviceservice
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 2020
+    targetPort: 2020
+    nodePort: 30221
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: computeservice-public
+spec:
+  type: NodePort
+  selector:
+    app: computeservice
+  ports:
+  - name: http
+    protocol: TCP
+    port: 8080
+    targetPort: 8080
+    nodePort: 30881
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: webuiservice-public
+  labels:
+    app: webuiservice
+spec:
+  type: NodePort
+  selector:
+    app: webuiservice
+  ports:
+  - name: http
+    protocol: TCP
+    port: 8004
+    targetPort: 8004
+    nodePort: 30801
+  - name: grafana
+    protocol: TCP
+    port: 3000
+    targetPort: 3000
+    nodePort: 30301
diff --git a/src/tests/oeccpsc22/expose_services_teraflow_2.yaml b/src/tests/oeccpsc22/expose_services_teraflow_2.yaml
new file mode 100644
index 000000000..8254c00aa
--- /dev/null
+++ b/src/tests/oeccpsc22/expose_services_teraflow_2.yaml
@@ -0,0 +1,106 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+apiVersion: v1
+kind: Service
+metadata:
+  name: remote-teraflow
+spec:
+  type: ExternalName
+  externalName: interdomainservice.oeccpsc22-1.svc.cluster.local
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 10010
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: contextservice-public
+  labels:
+    app: contextservice
+spec:
+  type: NodePort
+  selector:
+    app: contextservice
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 1010
+    targetPort: 1010
+    nodePort: 30112
+  - name: rest
+    protocol: TCP
+    port: 8080
+    targetPort: 8080
+    nodePort: 30002
+  - name: redis
+    protocol: TCP
+    port: 6379
+    targetPort: 6379
+    nodePort: 30632
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: deviceservice-public
+  labels:
+    app: deviceservice
+spec:
+  type: NodePort
+  selector:
+    app: deviceservice
+  ports:
+  - name: grpc
+    protocol: TCP
+    port: 2020
+    targetPort: 2020
+    nodePort: 30222
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: computeservice-public
+spec:
+  type: NodePort
+  selector:
+    app: computeservice
+  ports:
+  - name: http
+    protocol: TCP
+    port: 8080
+    targetPort: 8080
+    nodePort: 30882
+---
+apiVersion: v1
+kind: Service
+metadata:
+  name: webuiservice-public
+  labels:
+    app: webuiservice
+spec:
+  type: NodePort
+  selector:
+    app: webuiservice
+  ports:
+  - name: http
+    protocol: TCP
+    port: 8004
+    targetPort: 8004
+    nodePort: 30802
+  - name: grafana
+    protocol: TCP
+    port: 3000
+    targetPort: 3000
+    nodePort: 30302
diff --git a/src/tests/oeccpsc22/run_test_01_bootstrap.sh b/src/tests/oeccpsc22/run_test_01_bootstrap.sh
new file mode 100755
index 000000000..e8df6ffb6
--- /dev/null
+++ b/src/tests/oeccpsc22/run_test_01_bootstrap.sh
@@ -0,0 +1,60 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+COVERAGEFILE=$PROJECTDIR/coverage/.coverage
+
+# Configure the correct folder on the .coveragerc file
+cat $PROJECTDIR/coverage/.coveragerc.template | sed s+~/teraflow/controller+$PROJECTDIR+g > $RCFILE
+
+# Destroy old coverage file
+rm -f $COVERAGEFILE
+
+# Set the name of the Kubernetes namespace and hostname to use.
+K8S_NAMESPACE_D1="oeccpsc22-1"
+K8S_NAMESPACE_D2="oeccpsc22-2"
+# K8S_HOSTNAME="kubernetes-master"
+# dynamically gets the name of the K8s master node
+K8S_HOSTNAME=`kubectl get nodes --selector=node-role.kubernetes.io/master | tr -s " " | cut -f1 -d" " | sed -n '2 p'`
+
+# Flush Context database
+kubectl --namespace $K8S_NAMESPACE_D1 exec -it deployment/contextservice --container redis -- redis-cli FLUSHALL
+kubectl --namespace $K8S_NAMESPACE_D2 exec -it deployment/contextservice --container redis -- redis-cli FLUSHALL
+
+export D1_CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
+export D1_DEVICESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_DEVICESERVICE_SERVICE_PORT_GRPC=$(kubectl get service deviceservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==2020)].nodePort}')
+export D1_COMPUTESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service computeservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==8080)].nodePort}')
+
+export D2_CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
+export D2_DEVICESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_DEVICESERVICE_SERVICE_PORT_GRPC=$(kubectl get service deviceservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==2020)].nodePort}')
+export D2_COMPUTESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service computeservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==8080)].nodePort}')
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+# Run functional test and analyze coverage of code at same time
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    tests/oeccpsc22/tests/test_functional_bootstrap.py
diff --git a/src/tests/oeccpsc22/run_test_02_create_interdomain_slice.sh b/src/tests/oeccpsc22/run_test_02_create_interdomain_slice.sh
new file mode 100755
index 000000000..b9ab66cb3
--- /dev/null
+++ b/src/tests/oeccpsc22/run_test_02_create_interdomain_slice.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+COVERAGEFILE=$PROJECTDIR/coverage/.coverage
+
+# Set the name of the Kubernetes namespace and hostname to use.
+K8S_NAMESPACE_D1="oeccpsc22-1"
+K8S_NAMESPACE_D2="oeccpsc22-2"
+# dynamically gets the name of the K8s master node
+K8S_HOSTNAME=`kubectl get nodes --selector=node-role.kubernetes.io/master | tr -s " " | cut -f1 -d" " | sed -n '2 p'`
+
+export D1_CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
+export D1_DEVICESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_DEVICESERVICE_SERVICE_PORT_GRPC=$(kubectl get service deviceservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==2020)].nodePort}')
+export D1_COMPUTESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service computeservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==8080)].nodePort}')
+
+export D2_CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
+export D2_DEVICESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_DEVICESERVICE_SERVICE_PORT_GRPC=$(kubectl get service deviceservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==2020)].nodePort}')
+export D2_COMPUTESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service computeservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==8080)].nodePort}')
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+# Run functional test and analyze coverage of code at same time
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py
diff --git a/src/tests/oeccpsc22/run_test_03_delete_interdomain_slice.sh b/src/tests/oeccpsc22/run_test_03_delete_interdomain_slice.sh
new file mode 100755
index 000000000..b0080ce37
--- /dev/null
+++ b/src/tests/oeccpsc22/run_test_03_delete_interdomain_slice.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+COVERAGEFILE=$PROJECTDIR/coverage/.coverage
+
+# Set the name of the Kubernetes namespace and hostname to use.
+K8S_NAMESPACE_D1="oeccpsc22-1"
+K8S_NAMESPACE_D2="oeccpsc22-2"
+# dynamically gets the name of the K8s master node
+K8S_HOSTNAME=`kubectl get nodes --selector=node-role.kubernetes.io/master | tr -s " " | cut -f1 -d" " | sed -n '2 p'`
+
+export D1_CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
+export D1_DEVICESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_DEVICESERVICE_SERVICE_PORT_GRPC=$(kubectl get service deviceservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==2020)].nodePort}')
+export D1_COMPUTESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service computeservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==8080)].nodePort}')
+
+export D2_CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
+export D2_DEVICESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_DEVICESERVICE_SERVICE_PORT_GRPC=$(kubectl get service deviceservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==2020)].nodePort}')
+export D2_COMPUTESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service computeservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==8080)].nodePort}')
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+# Run functional test and analyze coverage of code at same time
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py
diff --git a/src/tests/oeccpsc22/run_test_04_cleanup.sh b/src/tests/oeccpsc22/run_test_04_cleanup.sh
new file mode 100755
index 000000000..d0420820c
--- /dev/null
+++ b/src/tests/oeccpsc22/run_test_04_cleanup.sh
@@ -0,0 +1,49 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+COVERAGEFILE=$PROJECTDIR/coverage/.coverage
+
+# Set the name of the Kubernetes namespace and hostname to use.
+K8S_NAMESPACE_D1="oeccpsc22-1"
+K8S_NAMESPACE_D2="oeccpsc22-2"
+# dynamically gets the name of the K8s master node
+K8S_HOSTNAME=`kubectl get nodes --selector=node-role.kubernetes.io/master | tr -s " " | cut -f1 -d" " | sed -n '2 p'`
+
+export D1_CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
+export D1_DEVICESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_DEVICESERVICE_SERVICE_PORT_GRPC=$(kubectl get service deviceservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==2020)].nodePort}')
+export D1_COMPUTESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D1_COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service computeservice-public --namespace $K8S_NAMESPACE_D1 -o 'jsonpath={.spec.ports[?(@.port==8080)].nodePort}')
+
+export D2_CONTEXTSERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_CONTEXTSERVICE_SERVICE_PORT_GRPC=$(kubectl get service contextservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==1010)].nodePort}')
+export D2_DEVICESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_DEVICESERVICE_SERVICE_PORT_GRPC=$(kubectl get service deviceservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==2020)].nodePort}')
+export D2_COMPUTESERVICE_SERVICE_HOST=$(kubectl get node $K8S_HOSTNAME -o 'jsonpath={.status.addresses[?(@.type=="InternalIP")].address}')
+export D2_COMPUTESERVICE_SERVICE_PORT_HTTP=$(kubectl get service computeservice-public --namespace $K8S_NAMESPACE_D2 -o 'jsonpath={.spec.ports[?(@.port==8080)].nodePort}')
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+# Run functional test and analyze coverage of code at same time
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    tests/oeccpsc22/tests/test_functional_cleanup.py
diff --git a/src/tests/oeccpsc22/show_deploy.sh b/src/tests/oeccpsc22/show_deploy.sh
new file mode 100755
index 000000000..90d691489
--- /dev/null
+++ b/src/tests/oeccpsc22/show_deploy.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Deploy TeraFlow instance 1
+printf "TeraFlow Instance 1:\n--------------------\n"
+export K8S_NAMESPACE="oeccpsc22-1"
+kubectl --namespace $K8S_NAMESPACE get all
+
+printf "\n\n"
+
+# Deploy TeraFlow instance 2
+printf "TeraFlow Instance 2:\n--------------------\n"
+export K8S_NAMESPACE="oeccpsc22-2"
+kubectl --namespace $K8S_NAMESPACE get all
diff --git a/src/tests/oeccpsc22/tests/.gitignore b/src/tests/oeccpsc22/tests/.gitignore
new file mode 100644
index 000000000..76cb708d1
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/.gitignore
@@ -0,0 +1,2 @@
+# Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc.
+Credentials.py
diff --git a/src/tests/oeccpsc22/tests/Objects_Domain_1.py b/src/tests/oeccpsc22/tests/Objects_Domain_1.py
new file mode 100644
index 000000000..8b26348c9
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/Objects_Domain_1.py
@@ -0,0 +1,133 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
+from common.tools.object_factory.Context import json_context, json_context_id
+from common.tools.object_factory.Device import (
+    json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, json_device_id)
+from common.tools.object_factory.Link import json_link, json_link_id
+from common.tools.object_factory.Topology import json_topology, json_topology_id
+from .Tools import get_link_uuid, json_endpoint_ids
+
+# ----- Context --------------------------------------------------------------------------------------------------------
+D1_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
+D1_CONTEXT    = json_context(DEFAULT_CONTEXT_UUID)
+
+# ----- Topology -------------------------------------------------------------------------------------------------------
+D1_TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=D1_CONTEXT_ID)
+D1_TOPOLOGY    = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=D1_CONTEXT_ID)
+
+# ----- Devices --------------------------------------------------------------------------------------------------------
+# Assume all devices have the same architecture of endpoints
+D1_DEVICE_ENDPOINT_DEFS = [
+    # Trunk ports
+    ('1/1', '25Gbps', []), ('1/2', '25Gbps', []), ('1/3', '25Gbps', []), ('1/4', '25Gbps', []),
+    # Inter-domain ports
+    ('2/1', '100Gbps', []), ('2/2', '100Gbps', []),
+    # Access ports
+    ('3/1', '10Gbps', []), ('3/2', '10Gbps', []), ('3/3', '10Gbps', []), ('3/4', '10Gbps', []),
+    ('3/5', '10Gbps', []), ('3/6', '10Gbps', []), ('3/7', '10Gbps', []), ('3/8', '10Gbps', []),
+]
+
+D1_DEVICE_D1R1_UUID          = 'R1@D1'
+D1_DEVICE_D1R1_ID            = json_device_id(D1_DEVICE_D1R1_UUID)
+D1_DEVICE_D1R1               = json_device_emulated_packet_router_disabled(D1_DEVICE_D1R1_UUID)
+D1_DEVICE_D1R1_CONNECT_RULES = json_device_emulated_connect_rules(D1_DEVICE_ENDPOINT_DEFS)
+
+D1_DEVICE_D1R2_UUID          = 'R2@D1'
+D1_DEVICE_D1R2_ID            = json_device_id(D1_DEVICE_D1R2_UUID)
+D1_DEVICE_D1R2               = json_device_emulated_packet_router_disabled(D1_DEVICE_D1R2_UUID)
+D1_DEVICE_D1R2_CONNECT_RULES = json_device_emulated_connect_rules(D1_DEVICE_ENDPOINT_DEFS)
+
+D1_DEVICE_D1R3_UUID          = 'R3@D1'
+D1_DEVICE_D1R3_ID            = json_device_id(D1_DEVICE_D1R3_UUID)
+D1_DEVICE_D1R3               = json_device_emulated_packet_router_disabled(D1_DEVICE_D1R3_UUID)
+D1_DEVICE_D1R3_CONNECT_RULES = json_device_emulated_connect_rules(D1_DEVICE_ENDPOINT_DEFS)
+
+D1_DEVICE_D1R4_UUID          = 'R4@D1'
+D1_DEVICE_D1R4_ID            = json_device_id(D1_DEVICE_D1R4_UUID)
+D1_DEVICE_D1R4               = json_device_emulated_packet_router_disabled(D1_DEVICE_D1R4_UUID)
+D1_DEVICE_D1R4_CONNECT_RULES = json_device_emulated_connect_rules(D1_DEVICE_ENDPOINT_DEFS)
+
+# Virtual devices on remote domains
+D1_DEVICE_D2R1_UUID          = 'R1@D2'
+D1_DEVICE_D2R1_ID            = json_device_id(D1_DEVICE_D2R1_UUID)
+D1_DEVICE_D2R1               = json_device_emulated_packet_router_disabled(D1_DEVICE_D2R1_UUID)
+D1_DEVICE_D2R1_CONNECT_RULES = json_device_emulated_connect_rules(D1_DEVICE_ENDPOINT_DEFS)
+
+D1_DEVICE_D2R4_UUID          = 'R4@D2'
+D1_DEVICE_D2R4_ID            = json_device_id(D1_DEVICE_D2R4_UUID)
+D1_DEVICE_D2R4               = json_device_emulated_packet_router_disabled(D1_DEVICE_D2R4_UUID)
+D1_DEVICE_D2R4_CONNECT_RULES = json_device_emulated_connect_rules(D1_DEVICE_ENDPOINT_DEFS)
+
+D1_ENDPOINT_IDS = {}
+D1_ENDPOINT_IDS.update(json_endpoint_ids(D1_DEVICE_D1R1_ID, D1_DEVICE_ENDPOINT_DEFS))
+D1_ENDPOINT_IDS.update(json_endpoint_ids(D1_DEVICE_D1R2_ID, D1_DEVICE_ENDPOINT_DEFS))
+D1_ENDPOINT_IDS.update(json_endpoint_ids(D1_DEVICE_D1R3_ID, D1_DEVICE_ENDPOINT_DEFS))
+D1_ENDPOINT_IDS.update(json_endpoint_ids(D1_DEVICE_D1R4_ID, D1_DEVICE_ENDPOINT_DEFS))
+D1_ENDPOINT_IDS.update(json_endpoint_ids(D1_DEVICE_D2R1_ID, D1_DEVICE_ENDPOINT_DEFS))
+D1_ENDPOINT_IDS.update(json_endpoint_ids(D1_DEVICE_D2R4_ID, D1_DEVICE_ENDPOINT_DEFS))
+
+
+# ----- Links ----------------------------------------------------------------------------------------------------------
+# Intra-domain links
+D1_LINK_D1R1_D1R2_UUID = get_link_uuid(
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R1_UUID]['1/2'], D1_ENDPOINT_IDS[D1_DEVICE_D1R2_UUID]['1/1'])
+D1_LINK_D1R1_D1R2_ID   = json_link_id(D1_LINK_D1R1_D1R2_UUID)
+D1_LINK_D1R1_D1R2      = json_link(D1_LINK_D1R1_D1R2_UUID, [
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R1_UUID]['1/2'], D1_ENDPOINT_IDS[D1_DEVICE_D1R2_UUID]['1/1']])
+
+D1_LINK_D1R2_D1R3_UUID = get_link_uuid(
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R2_UUID]['1/2'], D1_ENDPOINT_IDS[D1_DEVICE_D1R3_UUID]['1/1'])
+D1_LINK_D1R2_D1R3_ID   = json_link_id(D1_LINK_D1R2_D1R3_UUID)
+D1_LINK_D1R2_D1R3      = json_link(D1_LINK_D1R2_D1R3_UUID, [
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R2_UUID]['1/2'], D1_ENDPOINT_IDS[D1_DEVICE_D1R3_UUID]['1/1']])
+
+D1_LINK_D1R3_D1R4_UUID = get_link_uuid(
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R3_UUID]['1/2'], D1_ENDPOINT_IDS[D1_DEVICE_D1R4_UUID]['1/1'])
+D1_LINK_D1R3_D1R4_ID   = json_link_id(D1_LINK_D1R3_D1R4_UUID)
+D1_LINK_D1R3_D1R4      = json_link(D1_LINK_D1R3_D1R4_UUID, [
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R3_UUID]['1/2'], D1_ENDPOINT_IDS[D1_DEVICE_D1R4_UUID]['1/1']])
+
+D1_LINK_D1R4_D1R1_UUID = get_link_uuid(
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R4_UUID]['1/2'], D1_ENDPOINT_IDS[D1_DEVICE_D1R1_UUID]['1/1'])
+D1_LINK_D1R4_D1R1_ID   = json_link_id(D1_LINK_D1R4_D1R1_UUID)
+D1_LINK_D1R4_D1R1      = json_link(D1_LINK_D1R4_D1R1_UUID, [
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R4_UUID]['1/2'], D1_ENDPOINT_IDS[D1_DEVICE_D1R1_UUID]['1/1']])
+
+# Inter-domain links
+D1_LINK_D1R4_D2R1_UUID = get_link_uuid(
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R4_UUID]['2/1'], D1_ENDPOINT_IDS[D1_DEVICE_D2R1_UUID]['2/1'])
+D1_LINK_D1R4_D2R1_ID   = json_link_id(D1_LINK_D1R4_D2R1_UUID)
+D1_LINK_D1R4_D2R1      = json_link(D1_LINK_D1R4_D2R1_UUID, [
+    D1_ENDPOINT_IDS[D1_DEVICE_D1R4_UUID]['2/1'], D1_ENDPOINT_IDS[D1_DEVICE_D2R1_UUID]['2/1']])
+
+# ----- Object Collections ---------------------------------------------------------------------------------------------
+
+D1_CONTEXTS = [D1_CONTEXT]
+D1_TOPOLOGIES = [D1_TOPOLOGY]
+
+D1_DEVICES = [
+    (D1_DEVICE_D1R1, D1_DEVICE_D1R1_CONNECT_RULES),
+    (D1_DEVICE_D1R2, D1_DEVICE_D1R2_CONNECT_RULES),
+    (D1_DEVICE_D1R3, D1_DEVICE_D1R3_CONNECT_RULES),
+    (D1_DEVICE_D1R4, D1_DEVICE_D1R4_CONNECT_RULES),
+    (D1_DEVICE_D2R1, D1_DEVICE_D2R1_CONNECT_RULES),
+    (D1_DEVICE_D2R4, D1_DEVICE_D2R4_CONNECT_RULES),
+]
+
+D1_LINKS = [
+    D1_LINK_D1R1_D1R2, D1_LINK_D1R2_D1R3, D1_LINK_D1R3_D1R4, D1_LINK_D1R4_D1R1,
+    D1_LINK_D1R4_D2R1,
+]
diff --git a/src/tests/oeccpsc22/tests/Objects_Domain_2.py b/src/tests/oeccpsc22/tests/Objects_Domain_2.py
new file mode 100644
index 000000000..f91338092
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/Objects_Domain_2.py
@@ -0,0 +1,133 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
+from common.tools.object_factory.Context import json_context, json_context_id
+from common.tools.object_factory.Device import (
+    json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled, json_device_id)
+from common.tools.object_factory.Link import json_link, json_link_id
+from common.tools.object_factory.Topology import json_topology, json_topology_id
+from .Tools import get_link_uuid, json_endpoint_ids
+
+# ----- Context --------------------------------------------------------------------------------------------------------
+D2_CONTEXT_ID = json_context_id(DEFAULT_CONTEXT_UUID)
+D2_CONTEXT    = json_context(DEFAULT_CONTEXT_UUID)
+
+# ----- Topology -------------------------------------------------------------------------------------------------------
+D2_TOPOLOGY_ID = json_topology_id(DEFAULT_TOPOLOGY_UUID, context_id=D2_CONTEXT_ID)
+D2_TOPOLOGY    = json_topology(DEFAULT_TOPOLOGY_UUID, context_id=D2_CONTEXT_ID)
+
+# ----- Devices --------------------------------------------------------------------------------------------------------
+# Assume all devices have the same architecture of endpoints
+D2_DEVICE_ENDPOINT_DEFS = [
+    # Trunk ports
+    ('1/1', '25Gbps', []), ('1/2', '25Gbps', []), ('1/3', '25Gbps', []), ('1/4', '25Gbps', []),
+    # Inter-domain ports
+    ('2/1', '100Gbps', []), ('2/2', '100Gbps', []),
+    # Access ports
+    ('3/1', '10Gbps', []), ('3/2', '10Gbps', []), ('3/3', '10Gbps', []), ('3/4', '10Gbps', []),
+    ('3/5', '10Gbps', []), ('3/6', '10Gbps', []), ('3/7', '10Gbps', []), ('3/8', '10Gbps', []),
+]
+
+D2_DEVICE_D2R1_UUID          = 'R1@D2'
+D2_DEVICE_D2R1_ID            = json_device_id(D2_DEVICE_D2R1_UUID)
+D2_DEVICE_D2R1               = json_device_emulated_packet_router_disabled(D2_DEVICE_D2R1_UUID)
+D2_DEVICE_D2R1_CONNECT_RULES = json_device_emulated_connect_rules(D2_DEVICE_ENDPOINT_DEFS)
+
+D2_DEVICE_D2R2_UUID          = 'R2@D2'
+D2_DEVICE_D2R2_ID            = json_device_id(D2_DEVICE_D2R2_UUID)
+D2_DEVICE_D2R2               = json_device_emulated_packet_router_disabled(D2_DEVICE_D2R2_UUID)
+D2_DEVICE_D2R2_CONNECT_RULES = json_device_emulated_connect_rules(D2_DEVICE_ENDPOINT_DEFS)
+
+D2_DEVICE_D2R3_UUID          = 'R3@D2'
+D2_DEVICE_D2R3_ID            = json_device_id(D2_DEVICE_D2R3_UUID)
+D2_DEVICE_D2R3               = json_device_emulated_packet_router_disabled(D2_DEVICE_D2R3_UUID)
+D2_DEVICE_D2R3_CONNECT_RULES = json_device_emulated_connect_rules(D2_DEVICE_ENDPOINT_DEFS)
+
+D2_DEVICE_D2R4_UUID          = 'R4@D2'
+D2_DEVICE_D2R4_ID            = json_device_id(D2_DEVICE_D2R4_UUID)
+D2_DEVICE_D2R4               = json_device_emulated_packet_router_disabled(D2_DEVICE_D2R4_UUID)
+D2_DEVICE_D2R4_CONNECT_RULES = json_device_emulated_connect_rules(D2_DEVICE_ENDPOINT_DEFS)
+
+# Virtual devices on remote domains
+D2_DEVICE_D1R1_UUID          = 'R1@D1'
+D2_DEVICE_D1R1_ID            = json_device_id(D2_DEVICE_D1R1_UUID)
+D2_DEVICE_D1R1               = json_device_emulated_packet_router_disabled(D2_DEVICE_D1R1_UUID)
+D2_DEVICE_D1R1_CONNECT_RULES = json_device_emulated_connect_rules(D2_DEVICE_ENDPOINT_DEFS)
+
+D2_DEVICE_D1R4_UUID          = 'R4@D1'
+D2_DEVICE_D1R4_ID            = json_device_id(D2_DEVICE_D1R4_UUID)
+D2_DEVICE_D1R4               = json_device_emulated_packet_router_disabled(D2_DEVICE_D1R4_UUID)
+D2_DEVICE_D1R4_CONNECT_RULES = json_device_emulated_connect_rules(D2_DEVICE_ENDPOINT_DEFS)
+
+D2_ENDPOINT_IDS = {}
+D2_ENDPOINT_IDS.update(json_endpoint_ids(D2_DEVICE_D2R1_ID, D2_DEVICE_ENDPOINT_DEFS))
+D2_ENDPOINT_IDS.update(json_endpoint_ids(D2_DEVICE_D2R2_ID, D2_DEVICE_ENDPOINT_DEFS))
+D2_ENDPOINT_IDS.update(json_endpoint_ids(D2_DEVICE_D2R3_ID, D2_DEVICE_ENDPOINT_DEFS))
+D2_ENDPOINT_IDS.update(json_endpoint_ids(D2_DEVICE_D2R4_ID, D2_DEVICE_ENDPOINT_DEFS))
+D2_ENDPOINT_IDS.update(json_endpoint_ids(D2_DEVICE_D1R1_ID, D2_DEVICE_ENDPOINT_DEFS))
+D2_ENDPOINT_IDS.update(json_endpoint_ids(D2_DEVICE_D1R4_ID, D2_DEVICE_ENDPOINT_DEFS))
+
+
+# ----- Links ----------------------------------------------------------------------------------------------------------
+# Intra-domain links
+D2_LINK_D2R1_D2R2_UUID = get_link_uuid(
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R1_UUID]['1/2'], D2_ENDPOINT_IDS[D2_DEVICE_D2R2_UUID]['1/1'])
+D2_LINK_D2R1_D2R2_ID   = json_link_id(D2_LINK_D2R1_D2R2_UUID)
+D2_LINK_D2R1_D2R2      = json_link(D2_LINK_D2R1_D2R2_UUID, [
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R1_UUID]['1/2'], D2_ENDPOINT_IDS[D2_DEVICE_D2R2_UUID]['1/1']])
+
+D2_LINK_D2R2_D2R3_UUID = get_link_uuid(
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R2_UUID]['1/2'], D2_ENDPOINT_IDS[D2_DEVICE_D2R3_UUID]['1/1'])
+D2_LINK_D2R2_D2R3_ID   = json_link_id(D2_LINK_D2R2_D2R3_UUID)
+D2_LINK_D2R2_D2R3      = json_link(D2_LINK_D2R2_D2R3_UUID, [
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R2_UUID]['1/2'], D2_ENDPOINT_IDS[D2_DEVICE_D2R3_UUID]['1/1']])
+
+D2_LINK_D2R3_D2R4_UUID = get_link_uuid(
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R3_UUID]['1/2'], D2_ENDPOINT_IDS[D2_DEVICE_D2R4_UUID]['1/1'])
+D2_LINK_D2R3_D2R4_ID   = json_link_id(D2_LINK_D2R3_D2R4_UUID)
+D2_LINK_D2R3_D2R4      = json_link(D2_LINK_D2R3_D2R4_UUID, [
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R3_UUID]['1/2'], D2_ENDPOINT_IDS[D2_DEVICE_D2R4_UUID]['1/1']])
+
+D2_LINK_D2R4_D2R1_UUID = get_link_uuid(
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R4_UUID]['1/2'], D2_ENDPOINT_IDS[D2_DEVICE_D2R1_UUID]['1/1'])
+D2_LINK_D2R4_D2R1_ID   = json_link_id(D2_LINK_D2R4_D2R1_UUID)
+D2_LINK_D2R4_D2R1      = json_link(D2_LINK_D2R4_D2R1_UUID, [
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R4_UUID]['1/2'], D2_ENDPOINT_IDS[D2_DEVICE_D2R1_UUID]['1/1']])
+
+# Inter-domain links
+D2_LINK_D2R4_D1R1_UUID = get_link_uuid(
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R4_UUID]['2/1'], D2_ENDPOINT_IDS[D2_DEVICE_D1R1_UUID]['2/1'])
+D2_LINK_D2R4_D1R1_ID   = json_link_id(D2_LINK_D2R4_D1R1_UUID)
+D2_LINK_D2R4_D1R1      = json_link(D2_LINK_D2R4_D1R1_UUID, [
+    D2_ENDPOINT_IDS[D2_DEVICE_D2R4_UUID]['2/1'], D2_ENDPOINT_IDS[D2_DEVICE_D1R1_UUID]['2/1']])
+
+# ----- Object Collections ---------------------------------------------------------------------------------------------
+
+D2_CONTEXTS = [D2_CONTEXT]
+D2_TOPOLOGIES = [D2_TOPOLOGY]
+
+D2_DEVICES = [
+    (D2_DEVICE_D2R1, D2_DEVICE_D2R1_CONNECT_RULES),
+    (D2_DEVICE_D2R2, D2_DEVICE_D2R2_CONNECT_RULES),
+    (D2_DEVICE_D2R3, D2_DEVICE_D2R3_CONNECT_RULES),
+    (D2_DEVICE_D2R4, D2_DEVICE_D2R4_CONNECT_RULES),
+    (D2_DEVICE_D1R1, D2_DEVICE_D1R1_CONNECT_RULES),
+    (D2_DEVICE_D1R4, D2_DEVICE_D1R4_CONNECT_RULES),
+]
+
+D2_LINKS = [
+    D2_LINK_D2R1_D2R2, D2_LINK_D2R2_D2R3, D2_LINK_D2R3_D2R4, D2_LINK_D2R4_D2R1,
+    D2_LINK_D2R4_D1R1,
+]
diff --git a/src/tests/oeccpsc22/tests/Objects_Service.py b/src/tests/oeccpsc22/tests/Objects_Service.py
new file mode 100644
index 000000000..a9ffadc0f
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/Objects_Service.py
@@ -0,0 +1,37 @@
+from .Objects_Domain_1 import D1_DEVICE_D1R1_UUID, D1_ENDPOINT_IDS
+from .Objects_Domain_2 import D2_DEVICE_D2R4_UUID, D2_ENDPOINT_IDS
+from .Tools import compose_bearer, compose_service_endpoint_id
+
+# ----- WIM Service Settings -------------------------------------------------------------------------------------------
+WIM_SEP_D1R1_ID          = compose_service_endpoint_id(D1_ENDPOINT_IDS[D1_DEVICE_D1R1_UUID]['3/1'])
+WIM_SEP_D1R1_ROUTER_ID   = '10.10.10.1'
+WIM_SEP_D1R1_ROUTER_DIST = '65000:111'
+WIM_SEP_D1R1_SITE_ID     = '1'
+WIM_SEP_D1R1_BEARER      = compose_bearer(D1_ENDPOINT_IDS[D1_DEVICE_D1R1_UUID]['3/1'])
+WIM_SRV_D1R1_VLAN_ID     = 400
+
+WIM_SEP_D2R4_ID          = compose_service_endpoint_id(D2_ENDPOINT_IDS[D2_DEVICE_D2R4_UUID]['3/3'])
+WIM_SEP_D2R4_ROUTER_ID   = '20.20.20.1'
+WIM_SEP_D2R4_ROUTER_DIST = '65000:222'
+WIM_SEP_D2R4_SITE_ID     = '2'
+WIM_SEP_D2R4_BEARER      = compose_bearer(D2_ENDPOINT_IDS[D2_DEVICE_D2R4_UUID]['3/3'])
+WIM_SRV_D2R4_VLAN_ID     = 500
+
+WIM_USERNAME = 'admin'
+WIM_PASSWORD = 'admin'
+
+WIM_MAPPING  = [
+    {'device-id': D1_DEVICE_D1R1_UUID, 'service_endpoint_id': WIM_SEP_D1R1_ID,
+     'service_mapping_info': {'bearer': {'bearer-reference': WIM_SEP_D1R1_BEARER}, 'site-id': WIM_SEP_D1R1_SITE_ID}},
+    {'device-id': D2_DEVICE_D2R4_UUID, 'service_endpoint_id': WIM_SEP_D2R4_ID,
+     'service_mapping_info': {'bearer': {'bearer-reference': WIM_SEP_D2R4_BEARER}, 'site-id': WIM_SEP_D2R4_SITE_ID}},
+]
+WIM_SERVICE_TYPE = 'ELAN'
+WIM_SERVICE_CONNECTION_POINTS = [
+    {'service_endpoint_id': WIM_SEP_D1R1_ID,
+        'service_endpoint_encapsulation_type': 'dot1q',
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_D1R1_VLAN_ID}},
+    {'service_endpoint_id': WIM_SEP_D2R4_ID,
+        'service_endpoint_encapsulation_type': 'dot1q',
+        'service_endpoint_encapsulation_info': {'vlan': WIM_SRV_D2R4_VLAN_ID}},
+]
diff --git a/src/tests/oeccpsc22/tests/Tools.py b/src/tests/oeccpsc22/tests/Tools.py
new file mode 100644
index 000000000..a782b6bb3
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/Tools.py
@@ -0,0 +1,25 @@
+from typing import Dict, List, Tuple
+from common.tools.object_factory.EndPoint import json_endpoint_id
+
+def json_endpoint_ids(device_id : Dict, endpoint_descriptors : List[Tuple[str, str, List[int]]]):
+    return {
+        device_id['device_uuid']['uuid']: {
+            ep_uuid: json_endpoint_id(device_id, ep_uuid, topology_id=None)
+            for ep_uuid, _, _ in endpoint_descriptors
+        }
+    }
+
+def get_link_uuid(a_endpoint_id : Dict, z_endpoint_id : Dict) -> str:
+    return '{:s}/{:s}=={:s}/{:s}'.format(
+        a_endpoint_id['device_id']['device_uuid']['uuid'], a_endpoint_id['endpoint_uuid']['uuid'],
+        a_endpoint_id['device_id']['device_uuid']['uuid'], z_endpoint_id['endpoint_uuid']['uuid'])
+
+def compose_service_endpoint_id(endpoint_id):
+    device_uuid = endpoint_id['device_id']['device_uuid']['uuid']
+    endpoint_uuid = endpoint_id['endpoint_uuid']['uuid']
+    return ':'.join([device_uuid, endpoint_uuid])
+
+def compose_bearer(endpoint_id):
+    device_uuid = endpoint_id['device_id']['device_uuid']['uuid']
+    endpoint_uuid = endpoint_id['endpoint_uuid']['uuid']
+    return ':'.join([device_uuid, endpoint_uuid])
diff --git a/src/tests/oeccpsc22/tests/__init__.py b/src/tests/oeccpsc22/tests/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/tests/oeccpsc22/tests/test_functional_bootstrap.py b/src/tests/oeccpsc22/tests/test_functional_bootstrap.py
new file mode 100644
index 000000000..452394c01
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/test_functional_bootstrap.py
@@ -0,0 +1,213 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy, logging, pytest
+from common.Settings import get_setting
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import Context, ContextId, Device, Empty, Link, Topology
+from device.client.DeviceClient import DeviceClient
+from .Objects_Domain_1 import D1_CONTEXT_ID, D1_CONTEXTS, D1_DEVICES, D1_LINKS, D1_TOPOLOGIES
+from .Objects_Domain_2 import D2_CONTEXT_ID, D2_CONTEXTS, D2_DEVICES, D2_LINKS, D2_TOPOLOGIES
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+@pytest.fixture(scope='session')
+def d1_context_client():
+    _client = ContextClient(
+        get_setting('D1_CONTEXTSERVICE_SERVICE_HOST'), get_setting('D1_CONTEXTSERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def d1_device_client():
+    _client = DeviceClient(
+        get_setting('D1_DEVICESERVICE_SERVICE_HOST'), get_setting('D1_DEVICESERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def d2_context_client():
+    _client = ContextClient(
+        get_setting('D2_CONTEXTSERVICE_SERVICE_HOST'), get_setting('D2_CONTEXTSERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def d2_device_client():
+    _client = DeviceClient(
+        get_setting('D2_DEVICESERVICE_SERVICE_HOST'), get_setting('D2_DEVICESERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+
+def test_scenario_empty(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(context_client):
+        response = context_client.ListContexts(Empty())
+        assert len(response.contexts) == 0
+
+        response = context_client.ListDevices(Empty())
+        assert len(response.devices) == 0
+
+        response = context_client.ListLinks(Empty())
+        assert len(response.links) == 0
+
+    # ----- List entities - Ensure database is empty -------------------------------------------------------------------
+    per_domain(d1_context_client)
+    per_domain(d2_context_client)
+
+
+def test_prepare_scenario(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(contexts, topologies, context_client):
+        for context in contexts:
+            context_uuid = context['context_id']['context_uuid']['uuid']
+            LOGGER.info('Adding Context {:s}'.format(context_uuid))
+            response = context_client.SetContext(Context(**context))
+            assert response.context_uuid.uuid == context_uuid
+
+        for topology in topologies:
+            context_uuid = topology['topology_id']['context_id']['context_uuid']['uuid']
+            topology_uuid = topology['topology_id']['topology_uuid']['uuid']
+            LOGGER.info('Adding Topology {:s}/{:s}'.format(context_uuid, topology_uuid))
+            response = context_client.SetTopology(Topology(**topology))
+            assert response.context_id.context_uuid.uuid == context_uuid
+            assert response.topology_uuid.uuid == topology_uuid
+
+    # ----- Create Contexts and Topologies -----------------------------------------------------------------------------
+    per_domain(D1_CONTEXTS, D1_TOPOLOGIES, d1_context_client)
+    per_domain(D2_CONTEXTS, D2_TOPOLOGIES, d2_context_client)
+
+
+def test_scenario_ready(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(contexts, topologies, context_id, context_client):
+        response = context_client.ListContexts(Empty())
+        assert len(response.contexts) == len(contexts)
+
+        response = context_client.ListTopologies(ContextId(**context_id))
+        assert len(response.topologies) == len(topologies)
+
+        response = context_client.ListDevices(Empty())
+        assert len(response.devices) == 0
+
+        response = context_client.ListLinks(Empty())
+        assert len(response.links) == 0
+
+        response = context_client.ListSlices(ContextId(**context_id))
+        assert len(response.slices) == 0
+
+        response = context_client.ListServices(ContextId(**context_id))
+        assert len(response.services) == 0
+
+    # ----- List entities - Ensure scenario is ready -------------------------------------------------------------------
+    per_domain(D1_CONTEXTS, D1_TOPOLOGIES, D1_CONTEXT_ID, d1_context_client)
+    per_domain(D2_CONTEXTS, D2_TOPOLOGIES, D2_CONTEXT_ID, d2_context_client)
+
+
+def test_devices_bootstraping(
+    d1_device_client : DeviceClient,    # pylint: disable=redefined-outer-name
+    d2_device_client : DeviceClient):   # pylint: disable=redefined-outer-name
+
+    def per_domain(devices, device_client):
+        for device, connect_rules in devices:
+            device_uuid = device['device_id']['device_uuid']['uuid']
+            LOGGER.info('Adding Device {:s}'.format(device_uuid))
+            device_with_connect_rules = copy.deepcopy(device)
+            device_with_connect_rules['device_config']['config_rules'].extend(connect_rules)
+            response = device_client.AddDevice(Device(**device_with_connect_rules))
+            assert response.device_uuid.uuid == device_uuid
+
+    # ----- Create Devices and Validate Collected Events ---------------------------------------------------------------
+    per_domain(D1_DEVICES, d1_device_client)
+    per_domain(D2_DEVICES, d2_device_client)
+
+
+def test_devices_bootstrapped(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(contexts, topologies, devices, context_id, context_client):
+        response = context_client.ListContexts(Empty())
+        assert len(response.contexts) == len(contexts)
+
+        response = context_client.ListTopologies(ContextId(**context_id))
+        assert len(response.topologies) == len(topologies)
+
+        response = context_client.ListDevices(Empty())
+        assert len(response.devices) == len(devices)
+
+        response = context_client.ListLinks(Empty())
+        assert len(response.links) == 0
+
+        response = context_client.ListSlices(ContextId(**context_id))
+        assert len(response.slices) == 0
+
+        response = context_client.ListServices(ContextId(**context_id))
+        assert len(response.services) == 0
+
+    # ----- List entities - Ensure bevices are created -----------------------------------------------------------------
+    per_domain(D1_CONTEXTS, D1_TOPOLOGIES, D1_DEVICES, D1_CONTEXT_ID, d1_context_client)
+    per_domain(D2_CONTEXTS, D2_TOPOLOGIES, D2_DEVICES, D2_CONTEXT_ID, d2_context_client)
+
+
+def test_links_creation(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(links, context_client):
+        for link in links:
+            link_uuid = link['link_id']['link_uuid']['uuid']
+            LOGGER.info('Adding Link {:s}'.format(link_uuid))
+            response = context_client.SetLink(Link(**link))
+            assert response.link_uuid.uuid == link_uuid
+
+    # ----- Create Links and Validate Collected Events -----------------------------------------------------------------
+    per_domain(D1_LINKS, d1_context_client)
+    per_domain(D2_LINKS, d2_context_client)
+
+
+def test_links_created(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(contexts, topologies, devices, links, context_id, context_client):
+        response = context_client.ListContexts(Empty())
+        assert len(response.contexts) == len(contexts)
+
+        response = context_client.ListTopologies(ContextId(**context_id))
+        assert len(response.topologies) == len(topologies)
+
+        response = context_client.ListDevices(Empty())
+        assert len(response.devices) == len(devices)
+
+        response = context_client.ListLinks(Empty())
+        assert len(response.links) == len(links)
+
+        response = context_client.ListSlices(ContextId(**context_id))
+        assert len(response.slices) == 0
+
+        response = context_client.ListServices(ContextId(**context_id))
+        assert len(response.services) == 0
+
+    # ----- List entities - Ensure links are created -------------------------------------------------------------------
+    per_domain(D1_CONTEXTS, D1_TOPOLOGIES, D1_DEVICES, D1_LINKS, D1_CONTEXT_ID, d1_context_client)
+    per_domain(D2_CONTEXTS, D2_TOPOLOGIES, D2_DEVICES, D2_LINKS, D2_CONTEXT_ID, d2_context_client)
diff --git a/src/tests/oeccpsc22/tests/test_functional_cleanup.py b/src/tests/oeccpsc22/tests/test_functional_cleanup.py
new file mode 100644
index 000000000..eb78a5850
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/test_functional_cleanup.py
@@ -0,0 +1,123 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, pytest
+from common.Settings import get_setting
+from common.tests.EventTools import EVENT_REMOVE, check_events
+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.Link import json_link_id
+from common.tools.object_factory.Topology import json_topology_id
+from context.client.ContextClient import ContextClient
+from context.client.EventsCollector import EventsCollector
+from context.proto.context_pb2 import ContextId, DeviceId, Empty, LinkId, TopologyId
+from device.client.DeviceClient import DeviceClient
+from .Objects import CONTEXT_ID, CONTEXTS, DEVICES, LINKS, TOPOLOGIES
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+
+@pytest.fixture(scope='session')
+def context_client():
+    _client = ContextClient(get_setting('CONTEXTSERVICE_SERVICE_HOST'), get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+
+@pytest.fixture(scope='session')
+def device_client():
+    _client = DeviceClient(get_setting('DEVICESERVICE_SERVICE_HOST'), get_setting('DEVICESERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+
+def test_services_removed(context_client : ContextClient):  # pylint: disable=redefined-outer-name
+    # ----- List entities - Ensure service is removed ------------------------------------------------------------------
+    response = context_client.ListContexts(Empty())
+    assert len(response.contexts) == len(CONTEXTS)
+
+    response = context_client.ListTopologies(ContextId(**CONTEXT_ID))
+    assert len(response.topologies) == len(TOPOLOGIES)
+
+    response = context_client.ListDevices(Empty())
+    assert len(response.devices) == len(DEVICES)
+
+    response = context_client.ListLinks(Empty())
+    assert len(response.links) == len(LINKS)
+
+    response = context_client.ListServices(ContextId(**CONTEXT_ID))
+    assert len(response.services) == 0
+
+
+def test_scenario_cleanup(
+    context_client : ContextClient, device_client : DeviceClient):  # pylint: disable=redefined-outer-name
+
+    # ----- Start the EventsCollector ----------------------------------------------------------------------------------
+    events_collector = EventsCollector(context_client)
+    events_collector.start()
+
+    expected_events = []
+
+    # ----- Delete Links and Validate Collected Events -----------------------------------------------------------------
+    for link in LINKS:
+        link_id = link['link_id']
+        link_uuid = link_id['link_uuid']['uuid']
+        LOGGER.info('Deleting Link {:s}'.format(link_uuid))
+        context_client.RemoveLink(LinkId(**link_id))
+        expected_events.append(('LinkEvent', EVENT_REMOVE, json_link_id(link_uuid)))
+
+    # ----- Delete Devices and Validate Collected Events ---------------------------------------------------------------
+    for device, _ in DEVICES:
+        device_id = device['device_id']
+        device_uuid = device_id['device_uuid']['uuid']
+        LOGGER.info('Deleting Device {:s}'.format(device_uuid))
+        device_client.DeleteDevice(DeviceId(**device_id))
+        expected_events.append(('DeviceEvent', EVENT_REMOVE, json_device_id(device_uuid)))
+
+    # ----- Delete Topologies and Validate Collected Events ------------------------------------------------------------
+    for topology in TOPOLOGIES:
+        topology_id = topology['topology_id']
+        context_uuid = topology_id['context_id']['context_uuid']['uuid']
+        topology_uuid = topology_id['topology_uuid']['uuid']
+        LOGGER.info('Deleting Topology {:s}/{:s}'.format(context_uuid, topology_uuid))
+        context_client.RemoveTopology(TopologyId(**topology_id))
+        context_id = json_context_id(context_uuid)
+        expected_events.append(('TopologyEvent', EVENT_REMOVE, json_topology_id(topology_uuid, context_id=context_id)))
+
+    # ----- Delete Contexts and Validate Collected Events --------------------------------------------------------------
+    for context in CONTEXTS:
+        context_id = context['context_id']
+        context_uuid = context_id['context_uuid']['uuid']
+        LOGGER.info('Deleting Context {:s}'.format(context_uuid))
+        context_client.RemoveContext(ContextId(**context_id))
+        expected_events.append(('ContextEvent', EVENT_REMOVE, json_context_id(context_uuid)))
+
+    # ----- Validate Collected Events ----------------------------------------------------------------------------------
+    check_events(events_collector, expected_events)
+
+    # ----- Stop the EventsCollector -----------------------------------------------------------------------------------
+    events_collector.stop()
+
+
+def test_scenario_empty_again(context_client : ContextClient):  # pylint: disable=redefined-outer-name
+    # ----- List entities - Ensure database is empty again -------------------------------------------------------------
+    response = context_client.ListContexts(Empty())
+    assert len(response.contexts) == 0
+
+    response = context_client.ListDevices(Empty())
+    assert len(response.devices) == 0
+
+    response = context_client.ListLinks(Empty())
+    assert len(response.links) == 0
diff --git a/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py b/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py
new file mode 100644
index 000000000..e6f6ccbc9
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/test_functional_create_interdomain_slice.py
@@ -0,0 +1,129 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, pytest
+from common.DeviceTypes import DeviceTypeEnum
+from common.Settings import get_setting
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from compute.tests.mock_osm.MockOSM import MockOSM
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import ContextId, Empty
+from .Objects_Domain_1 import D1_CONTEXT_ID, D1_CONTEXTS, D1_DEVICES, D1_LINKS, D1_TOPOLOGIES
+from .Objects_Domain_2 import D2_CONTEXT_ID, D2_CONTEXTS, D2_DEVICES, D2_LINKS, D2_TOPOLOGIES
+from .Objects_Service import WIM_MAPPING, WIM_PASSWORD, WIM_SERVICE_CONNECTION_POINTS, WIM_SERVICE_TYPE, WIM_USERNAME
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DEVTYPE_EMU_PR  = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value
+DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPTICAL_LINE_SYSTEM.value
+
+
+@pytest.fixture(scope='session')
+def d1_context_client():
+    _client = ContextClient(
+        get_setting('D1_CONTEXTSERVICE_SERVICE_HOST'), get_setting('D1_CONTEXTSERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+
+@pytest.fixture(scope='session')
+def d2_context_client():
+    _client = ContextClient(
+        get_setting('D2_CONTEXTSERVICE_SERVICE_HOST'), get_setting('D2_CONTEXTSERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+
+@pytest.fixture(scope='session')
+def d1_osm_wim():
+    wim_url = 'http://{:s}:{:s}'.format(
+        get_setting('D1_COMPUTESERVICE_SERVICE_HOST'), str(get_setting('D1_COMPUTESERVICE_SERVICE_PORT_HTTP')))
+    return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)
+
+
+def test_scenario_is_correct(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(contexts, topologies, devices, links, context_id, context_client):
+        response = context_client.ListContexts(Empty())
+        assert len(response.contexts) == len(contexts)
+
+        response = context_client.ListTopologies(ContextId(**context_id))
+        assert len(response.topologies) == len(topologies)
+
+        response = context_client.ListDevices(Empty())
+        assert len(response.devices) == len(devices)
+
+        response = context_client.ListLinks(Empty())
+        assert len(response.links) == len(links)
+
+        response = context_client.ListSlices(ContextId(**context_id))
+        assert len(response.slices) == 0
+
+        response = context_client.ListServices(ContextId(**context_id))
+        assert len(response.services) == 0
+
+    # ----- List entities - Ensure scenario is up ----------------------------------------------------------------------
+    per_domain(D1_CONTEXTS, D1_TOPOLOGIES, D1_DEVICES, D1_LINKS, D1_CONTEXT_ID, d1_context_client)
+    per_domain(D2_CONTEXTS, D2_TOPOLOGIES, D2_DEVICES, D2_LINKS, D2_CONTEXT_ID, d2_context_client)
+
+
+def test_interdomain_slice_creation(
+    d1_osm_wim : MockOSM):              # pylint: disable=redefined-outer-name
+
+    # ----- Create Inter-domain Slice ----------------------------------------------------------------------------------
+    service_uuid = d1_osm_wim.create_connectivity_service(WIM_SERVICE_TYPE, WIM_SERVICE_CONNECTION_POINTS)
+    d1_osm_wim.get_connectivity_service_status(service_uuid)
+
+
+def test_scenario_interdomain_slice_created(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(contexts, topologies, devices, links, context_id, context_client):
+        response = context_client.ListContexts(Empty())
+        assert len(response.contexts) == len(contexts)
+
+        response = context_client.ListTopologies(ContextId(**context_id))
+        assert len(response.topologies) == len(topologies)
+
+        response = context_client.ListDevices(Empty())
+        assert len(response.devices) == len(devices)
+
+        response = context_client.ListLinks(Empty())
+        assert len(response.links) == len(links)
+
+        # TODO: implement validation of number of slices according to the domain they belong
+        #response = context_client.ListSlices(ContextId(**context_id))
+        #LOGGER.info('Slices[{:d}] = {:s}'.format(len(response.slices), grpc_message_to_json_string(response)))
+        #assert len(response.slices) == (2 if D1 else 1)
+        # TODO: implement validation that slices are correct
+
+        response = context_client.ListServices(ContextId(**context_id))
+        LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response)))
+        assert len(response.services) == 1 # L3NM
+        # TODO: improve validation of services created
+        for service in response.services:
+            service_id = service.service_id
+            response = context_client.ListConnections(service_id)
+            LOGGER.info('  ServiceId[{:s}] => Connections[{:d}] = {:s}'.format(
+                grpc_message_to_json_string(service_id), len(response.connections),
+                grpc_message_to_json_string(response)))
+            assert len(response.connections) == 1 # one connection per service
+
+    # ----- List entities - Ensure service is created ------------------------------------------------------------------
+    per_domain(D1_CONTEXTS, D1_TOPOLOGIES, D1_DEVICES, D1_LINKS, D1_CONTEXT_ID, d1_context_client)
+    per_domain(D2_CONTEXTS, D2_TOPOLOGIES, D2_DEVICES, D2_LINKS, D2_CONTEXT_ID, d2_context_client)
diff --git a/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py b/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py
new file mode 100644
index 000000000..2830225be
--- /dev/null
+++ b/src/tests/oeccpsc22/tests/test_functional_delete_interdomain_slice.py
@@ -0,0 +1,143 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, pytest
+from common.DeviceTypes import DeviceTypeEnum
+from common.Settings import get_setting
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from compute.tests.mock_osm.MockOSM import MockOSM
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import ContextId, Empty
+from .Objects_Domain_1 import D1_CONTEXT_ID, D1_CONTEXTS, D1_DEVICES, D1_LINKS, D1_TOPOLOGIES
+from .Objects_Domain_2 import D2_CONTEXT_ID, D2_CONTEXTS, D2_DEVICES, D2_LINKS, D2_TOPOLOGIES
+from .Objects_Service import WIM_MAPPING, WIM_PASSWORD, WIM_USERNAME
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+DEVTYPE_EMU_PR  = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value
+DEVTYPE_EMU_OLS = DeviceTypeEnum.EMULATED_OPTICAL_LINE_SYSTEM.value
+
+
+@pytest.fixture(scope='session')
+def d1_context_client():
+    _client = ContextClient(
+        get_setting('D1_CONTEXTSERVICE_SERVICE_HOST'), get_setting('D1_CONTEXTSERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+
+@pytest.fixture(scope='session')
+def d2_context_client():
+    _client = ContextClient(
+        get_setting('D2_CONTEXTSERVICE_SERVICE_HOST'), get_setting('D2_CONTEXTSERVICE_SERVICE_PORT_GRPC'))
+    yield _client
+    _client.close()
+
+
+@pytest.fixture(scope='session')
+def d1_osm_wim():
+    wim_url = 'http://{:s}:{:s}'.format(
+        get_setting('D1_COMPUTESERVICE_SERVICE_HOST'), str(get_setting('D1_COMPUTESERVICE_SERVICE_PORT_HTTP')))
+    return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)
+
+
+def test_interdomain_slice_created(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(contexts, topologies, devices, links, context_id, context_client):
+        response = context_client.ListContexts(Empty())
+        assert len(response.contexts) == len(contexts)
+
+        response = context_client.ListTopologies(ContextId(**context_id))
+        assert len(response.topologies) == len(topologies)
+
+        response = context_client.ListDevices(Empty())
+        assert len(response.devices) == len(devices)
+
+        response = context_client.ListLinks(Empty())
+        assert len(response.links) == len(links)
+
+        # TODO: implement validation of number of slices according to the domain they belong
+        #response = context_client.ListSlices(ContextId(**context_id))
+        #LOGGER.info('Slices[{:d}] = {:s}'.format(len(response.slices), grpc_message_to_json_string(response)))
+        #assert len(response.slices) == (2 if D1 else 1)
+        # TODO: implement validation that slices are correct
+
+        response = context_client.ListServices(ContextId(**context_id))
+        LOGGER.info('Services[{:d}] = {:s}'.format(len(response.services), grpc_message_to_json_string(response)))
+        assert len(response.services) == 1 # L3NM
+        # TODO: improve validation of services created
+        for service in response.services:
+            service_id = service.service_id
+            response = context_client.ListConnections(service_id)
+            LOGGER.info('  ServiceId[{:s}] => Connections[{:d}] = {:s}'.format(
+                grpc_message_to_json_string(service_id), len(response.connections),
+                grpc_message_to_json_string(response)))
+            assert len(response.connections) == 1 # one connection per service
+
+    # ----- List entities - Ensure Inter-domain slice is created -------------------------------------------------------
+    per_domain(D1_CONTEXTS, D1_TOPOLOGIES, D1_DEVICES, D1_LINKS, D1_CONTEXT_ID, d1_context_client)
+    per_domain(D2_CONTEXTS, D2_TOPOLOGIES, D2_DEVICES, D2_LINKS, D2_CONTEXT_ID, d2_context_client)
+
+
+def test_interdomain_slice_removal(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d1_osm_wim : MockOSM):              # pylint: disable=redefined-outer-name
+
+    # ----- Remove Inter-domain Slice ----------------------------------------------------------------------------------
+    # TODO: implement retrieval of inter-domain slice to be deleted
+    #response = d1_context_client.ListSliceIds(ContextId(**D1_CONTEXT_ID))
+    #LOGGER.info('SliceIds[{:d}] = {:s}'.format(len(response.slice_ids), grpc_message_to_json_string(response)))
+    #assert len(response.service_ids) == 2 # L3NM + TAPI
+    #service_uuids = set()
+    #for service_id in response.service_ids:
+    #    service_uuid = service_id.service_uuid.uuid
+    #    if service_uuid.endswith(':optical'): continue
+    #    service_uuids.add(service_uuid)
+    #    osm_wim.conn_info[service_uuid] = {}
+
+    # TODO: implement removal of service
+    #assert len(service_uuids) == 1  # assume a single service has been created
+    #service_uuid = set(service_uuids).pop()
+    #osm_wim.delete_connectivity_service(service_uuid)
+
+
+def test_interdomain_slice_removed(
+    d1_context_client : ContextClient,  # pylint: disable=redefined-outer-name
+    d2_context_client : ContextClient): # pylint: disable=redefined-outer-name
+
+    def per_domain(contexts, topologies, devices, links, context_id, context_client):
+        response = context_client.ListContexts(Empty())
+        assert len(response.contexts) == len(contexts)
+
+        response = context_client.ListTopologies(ContextId(**context_id))
+        assert len(response.topologies) == len(topologies)
+
+        response = context_client.ListDevices(Empty())
+        assert len(response.devices) == len(devices)
+
+        response = context_client.ListLinks(Empty())
+        assert len(response.links) == len(links)
+
+        response = context_client.ListSlices(ContextId(**context_id))
+        assert len(response.slices) == 0
+
+        response = context_client.ListServices(ContextId(**context_id))
+        assert len(response.services) == 0
+
+    # ----- List entities - Ensure services removed --------------------------------------------------------------------
+    per_domain(D1_CONTEXTS, D1_TOPOLOGIES, D1_DEVICES, D1_LINKS, D1_CONTEXT_ID, d1_context_client)
+    per_domain(D2_CONTEXTS, D2_TOPOLOGIES, D2_DEVICES, D2_LINKS, D2_CONTEXT_ID, d2_context_client)
diff --git a/src/webui/genproto.sh b/src/webui/genproto.sh
index 18a0d4f92..290ae0294 100755
--- a/src/webui/genproto.sh
+++ b/src/webui/genproto.sh
@@ -1,6 +1,6 @@
 #!/bin/bash -eu
 #
-# Copyright 2018 Google LLC
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -14,14 +14,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-#!/bin/bash -e
-
 # Make folder containing the script the root folder for its execution
 cd $(dirname $0)
 
 rm -rf proto/*.py
 rm -rf proto/__pycache__
-touch proto/__init__.py
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
 
 # building protos of services used
 # python -m grpc_tools.protoc -I../../proto --python_out=proto --grpc_python_out=proto compute.proto
diff --git a/src/webui/proto/context_pb2.py b/src/webui/proto/context_pb2.py
index 68602b16f..50d501d3a 100644
--- a/src/webui/proto/context_pb2.py
+++ b/src/webui/proto/context_pb2.py
@@ -21,7 +21,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xad\x10\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
   ,
   dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
 
@@ -55,8 +55,8 @@ _EVENTTYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3703,
-  serialized_end=3809,
+  serialized_start=4310,
+  serialized_end=4416,
 )
 _sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
 
@@ -101,8 +101,8 @@ _DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=3812,
-  serialized_end=4009,
+  serialized_start=4419,
+  serialized_end=4616,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
 
@@ -132,8 +132,8 @@ _DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4012,
-  serialized_end=4155,
+  serialized_start=4619,
+  serialized_end=4762,
 )
 _sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
 
@@ -168,8 +168,8 @@ _SERVICETYPEENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4158,
-  serialized_end=4287,
+  serialized_start=4765,
+  serialized_end=4894,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
 
@@ -204,12 +204,53 @@ _SERVICESTATUSENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4290,
-  serialized_end=4426,
+  serialized_start=4897,
+  serialized_end=5033,
 )
 _sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
 
 ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
 _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   name='ConfigActionEnum',
   full_name='context.ConfigActionEnum',
@@ -235,8 +276,8 @@ _CONFIGACTIONENUM = _descriptor.EnumDescriptor(
   ],
   containing_type=None,
   serialized_options=None,
-  serialized_start=4428,
-  serialized_end=4521,
+  serialized_start=5177,
+  serialized_end=5270,
 )
 _sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
 
@@ -262,6 +303,11 @@ SERVICESTATUS_UNDEFINED = 0
 SERVICESTATUS_PLANNED = 1
 SERVICESTATUS_ACTIVE = 2
 SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
 CONFIGACTION_UNDEFINED = 0
 CONFIGACTION_SET = 1
 CONFIGACTION_DELETE = 2
@@ -1421,6 +1467,247 @@ _SERVICEEVENT = _descriptor.Descriptor(
 )
 
 
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
 _CONNECTIONID = _descriptor.Descriptor(
   name='ConnectionId',
   full_name='context.ConnectionId',
@@ -1448,8 +1735,8 @@ _CONNECTIONID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2604,
-  serialized_end=2658,
+  serialized_start=3211,
+  serialized_end=3265,
 )
 
 
@@ -1501,8 +1788,8 @@ _CONNECTION = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2661,
-  serialized_end=2857,
+  serialized_start=3268,
+  serialized_end=3464,
 )
 
 
@@ -1533,8 +1820,8 @@ _CONNECTIONIDLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2859,
-  serialized_end=2924,
+  serialized_start=3466,
+  serialized_end=3531,
 )
 
 
@@ -1565,8 +1852,8 @@ _CONNECTIONLIST = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2926,
-  serialized_end=2984,
+  serialized_start=3533,
+  serialized_end=3591,
 )
 
 
@@ -1604,8 +1891,8 @@ _CONNECTIONEVENT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=2986,
-  serialized_end=3080,
+  serialized_start=3593,
+  serialized_end=3687,
 )
 
 
@@ -1650,8 +1937,8 @@ _ENDPOINTID = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3083,
-  serialized_end=3213,
+  serialized_start=3690,
+  serialized_end=3820,
 )
 
 
@@ -1696,8 +1983,8 @@ _ENDPOINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3216,
-  serialized_end=3350,
+  serialized_start=3823,
+  serialized_end=3957,
 )
 
 
@@ -1742,8 +2029,8 @@ _CONFIGRULE = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3352,
-  serialized_end=3453,
+  serialized_start=3959,
+  serialized_end=4060,
 )
 
 
@@ -1781,8 +2068,8 @@ _CONSTRAINT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3455,
-  serialized_end=3518,
+  serialized_start=4062,
+  serialized_end=4125,
 )
 
 
@@ -1827,8 +2114,8 @@ _TERAFLOWCONTROLLER = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3520,
-  serialized_end=3614,
+  serialized_start=4127,
+  serialized_end=4221,
 )
 
 
@@ -1866,8 +2153,8 @@ _AUTHENTICATIONRESULT = _descriptor.Descriptor(
   extension_ranges=[],
   oneofs=[
   ],
-  serialized_start=3616,
-  serialized_end=3701,
+  serialized_start=4223,
+  serialized_end=4308,
 )
 
 _EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
@@ -1921,6 +2208,19 @@ _SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
 _SERVICELIST.fields_by_name['services'].message_type = _SERVICE
 _SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
 _SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
 _CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
 _CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
 _CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
@@ -1969,6 +2269,12 @@ DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
 DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
 DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
 DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
 DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
 DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
 DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
@@ -1985,6 +2291,7 @@ DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
 DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
 DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
 DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
 DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
 _sym_db.RegisterFileDescriptor(DESCRIPTOR)
 
@@ -2205,6 +2512,48 @@ ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_messag
   })
 _sym_db.RegisterMessage(ServiceEvent)
 
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
 ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
   'DESCRIPTOR' : _CONNECTIONID,
   '__module__' : 'context_pb2'
@@ -2291,8 +2640,8 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   index=0,
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_start=4524,
-  serialized_end=6617,
+  serialized_start=5273,
+  serialized_end=7688,
   methods=[
   _descriptor.MethodDescriptor(
     name='ListContextIds',
@@ -2594,10 +2943,70 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
   _descriptor.MethodDescriptor(
     name='ListConnectionIds',
     full_name='context.ContextService.ListConnectionIds',
-    index=30,
+    index=36,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONIDLIST,
@@ -2607,7 +3016,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='ListConnections',
     full_name='context.ContextService.ListConnections',
-    index=31,
+    index=37,
     containing_service=None,
     input_type=_SERVICEID,
     output_type=_CONNECTIONLIST,
@@ -2617,7 +3026,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnection',
     full_name='context.ContextService.GetConnection',
-    index=32,
+    index=38,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_CONNECTION,
@@ -2627,7 +3036,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='SetConnection',
     full_name='context.ContextService.SetConnection',
-    index=33,
+    index=39,
     containing_service=None,
     input_type=_CONNECTION,
     output_type=_CONNECTIONID,
@@ -2637,7 +3046,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='RemoveConnection',
     full_name='context.ContextService.RemoveConnection',
-    index=34,
+    index=40,
     containing_service=None,
     input_type=_CONNECTIONID,
     output_type=_EMPTY,
@@ -2647,7 +3056,7 @@ _CONTEXTSERVICE = _descriptor.ServiceDescriptor(
   _descriptor.MethodDescriptor(
     name='GetConnectionEvents',
     full_name='context.ContextService.GetConnectionEvents',
-    index=35,
+    index=41,
     containing_service=None,
     input_type=_EMPTY,
     output_type=_CONNECTIONEVENT,
diff --git a/src/webui/proto/service_pb2.py b/src/webui/proto/service_pb2.py
index 7a006915b..8e2806c76 100644
--- a/src/webui/proto/service_pb2.py
+++ b/src/webui/proto/service_pb2.py
@@ -20,7 +20,7 @@ DESCRIPTOR = _descriptor.FileDescriptor(
   syntax='proto3',
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
-  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xfd\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12\x42\n\x11GetConnectionList\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x62\x06proto3'
+  serialized_pb=b'\n\rservice.proto\x12\x07service\x1a\rcontext.proto2\xb9\x01\n\x0eServiceService\x12\x37\n\rCreateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x37\n\rUpdateService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rDeleteService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x62\x06proto3'
   ,
   dependencies=[context__pb2.DESCRIPTOR,])
 
@@ -38,7 +38,7 @@ _SERVICESERVICE = _descriptor.ServiceDescriptor(
   serialized_options=None,
   create_key=_descriptor._internal_create_key,
   serialized_start=42,
-  serialized_end=295,
+  serialized_end=227,
   methods=[
   _descriptor.MethodDescriptor(
     name='CreateService',
@@ -70,16 +70,6 @@ _SERVICESERVICE = _descriptor.ServiceDescriptor(
     serialized_options=None,
     create_key=_descriptor._internal_create_key,
   ),
-  _descriptor.MethodDescriptor(
-    name='GetConnectionList',
-    full_name='service.ServiceService.GetConnectionList',
-    index=3,
-    containing_service=None,
-    input_type=context__pb2._SERVICEID,
-    output_type=context__pb2._CONNECTIONLIST,
-    serialized_options=None,
-    create_key=_descriptor._internal_create_key,
-  ),
 ])
 _sym_db.RegisterServiceDescriptor(_SERVICESERVICE)
 
-- 
GitLab


From 719666465ea9b2c655fb9f3755d0c54cff7414e0 Mon Sep 17 00:00:00 2001
From: Roberto Rubino <roberto.rubino@siaemic.com>
Date: Mon, 16 May 2022 10:44:44 +0000
Subject: [PATCH 04/60] new development of microwave device - implemented the
 Api to get configurations, create and delete services

---
 scripts/run_test_microwave_device.sh          |  28 ++
 src/common/DeviceTypes.py                     |   1 +
 src/common/tools/object_factory/Device.py     |  11 +
 src/device/requirements.in                    |   1 +
 src/device/service/drivers/__init__.py        |   7 +
 .../drivers/microwave/IETFApiDriver.py        | 112 +++++++
 src/device/service/drivers/microwave/Tools.py | 177 ++++++++++
 .../service/drivers/microwave/__init__.py     |  27 ++
 src/device/tests/Device_Microwave_Template.py |  46 +++
 src/device/tests/test_unitary_microwave.py    | 316 ++++++++++++++++++
 10 files changed, 726 insertions(+)
 create mode 100755 scripts/run_test_microwave_device.sh
 create mode 100644 src/device/service/drivers/microwave/IETFApiDriver.py
 create mode 100644 src/device/service/drivers/microwave/Tools.py
 create mode 100644 src/device/service/drivers/microwave/__init__.py
 create mode 100644 src/device/tests/Device_Microwave_Template.py
 create mode 100644 src/device/tests/test_unitary_microwave.py

diff --git a/scripts/run_test_microwave_device.sh b/scripts/run_test_microwave_device.sh
new file mode 100755
index 000000000..34317b564
--- /dev/null
+++ b/scripts/run_test_microwave_device.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+coverage run --rcfile=$RCFILE --append -m pytest -s --log-level=INFO --verbose \
+    device/tests/test_unitary_microwave.py
diff --git a/src/common/DeviceTypes.py b/src/common/DeviceTypes.py
index 44f8e3981..bf871a2d5 100644
--- a/src/common/DeviceTypes.py
+++ b/src/common/DeviceTypes.py
@@ -17,6 +17,7 @@ from enum import Enum
 class DeviceTypeEnum(Enum):
     EMULATED_OPTICAL_LINE_SYSTEM = 'emu-optical-line-system'
     EMULATED_PACKET_ROUTER       = 'emu-packet-router'
+    MICROVAWE_RADIO_SYSTEM       = 'microwave-radio-system'
     OPTICAL_ROADM                = 'optical-roadm'
     OPTICAL_TRANDPONDER          = 'optical-trandponder'
     OPTICAL_LINE_SYSTEM          = 'optical-line-system'
diff --git a/src/common/tools/object_factory/Device.py b/src/common/tools/object_factory/Device.py
index ae065e9c0..c4ef8173c 100644
--- a/src/common/tools/object_factory/Device.py
+++ b/src/common/tools/object_factory/Device.py
@@ -32,6 +32,10 @@ DEVICE_PR_DRIVERS   = [DeviceDriverEnum.DEVICEDRIVER_OPENCONFIG]
 DEVICE_TAPI_TYPE    = DeviceTypeEnum.OPTICAL_LINE_SYSTEM.value
 DEVICE_TAPI_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_TRANSPORT_API]
 
+# check which enum type and value assign to microwave device
+DEVICE_MICROWAVE_TYPE    = DeviceTypeEnum.MICROVAWE_RADIO_SYSTEM.value
+DEVICE_MICROWAVE_DRIVERS = [DeviceDriverEnum.DEVICEDRIVER_IETF_NETWORK_TOPOLOGY]
+
 DEVICE_P4_TYPE      = DeviceTypeEnum.P4_SWITCH.value
 DEVICE_P4_DRIVERS   = [DeviceDriverEnum.DEVICEDRIVER_P4]
 
@@ -81,6 +85,13 @@ def json_device_tapi_disabled(
     return json_device(
         device_uuid, DEVICE_TAPI_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules, drivers=drivers)
 
+def json_device_microwave_disabled(
+        device_uuid : str, endpoints : List[Dict] = [], config_rules : List[Dict] = [],
+        drivers : List[Dict] = DEVICE_MICROWAVE_DRIVERS
+    ):
+    return json_device(
+        device_uuid, DEVICE_MICROWAVE_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules, drivers=drivers)
+
 def json_device_p4_disabled(
         device_uuid : str, endpoints : List[Dict] = [], config_rules : List[Dict] = [],
         drivers : List[Dict] = DEVICE_P4_DRIVERS
diff --git a/src/device/requirements.in b/src/device/requirements.in
index dde08cf19..d1af1e219 100644
--- a/src/device/requirements.in
+++ b/src/device/requirements.in
@@ -3,6 +3,7 @@ APScheduler==3.8.1
 fastcache==1.1.0
 grpcio==1.43.0
 grpcio-health-checking==1.43.0
+grpcio-tools==1.43.0
 Jinja2==3.0.3
 netconf-client==2.0.0 #1.7.3
 p4runtime==1.3.0
diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py
index 7479d4364..664b52821 100644
--- a/src/device/service/drivers/__init__.py
+++ b/src/device/service/drivers/__init__.py
@@ -18,6 +18,7 @@ from .emulated.EmulatedDriver import EmulatedDriver
 from .openconfig.OpenConfigDriver import OpenConfigDriver
 from .transport_api.TransportApiDriver import TransportApiDriver
 from .p4.p4_driver import P4Driver
+from .microwave.IETFApiDriver import IETFApiDriver
 
 DRIVERS = [
     (EmulatedDriver, [
@@ -51,4 +52,10 @@ DRIVERS = [
             FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.P4,
         }
     ]),
+    (IETFApiDriver, [
+        {
+            FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.MICROVAWE_RADIO_SYSTEM,
+            FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.IETF_NETWORK_TOPOLOGY,
+        }
+    ]),
 ]
diff --git a/src/device/service/drivers/microwave/IETFApiDriver.py b/src/device/service/drivers/microwave/IETFApiDriver.py
new file mode 100644
index 000000000..714a149b6
--- /dev/null
+++ b/src/device/service/drivers/microwave/IETFApiDriver.py
@@ -0,0 +1,112 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, requests, threading
+from typing import Any, Iterator, List, Optional, Tuple, Union
+from common.type_checkers.Checkers import chk_string, chk_type
+from device.service.driver_api._Driver import _Driver
+from . import ALL_RESOURCE_KEYS
+from .Tools import create_connectivity_service, find_key, config_getter, delete_connectivity_service
+
+LOGGER = logging.getLogger(__name__)
+
+class IETFApiDriver(_Driver):
+    def __init__(self, address: str, port: int, **settings) -> None:    # pylint: disable=super-init-not-called
+        self.__lock = threading.Lock()
+        self.__started = threading.Event()
+        self.__terminate = threading.Event()
+        self.__tapi_root = 'https://' + address + ':' + str(port)
+        self.__timeout = int(settings.get('timeout', 120))
+
+    def Connect(self) -> bool:
+        url = self.__tapi_root + '/nmswebs/restconf/data/ietf-network:networks'
+        with self.__lock:
+            if self.__started.is_set(): return True
+            try:
+                requests.get(url, timeout=self.__timeout, verify=False)
+            except requests.exceptions.Timeout:
+                LOGGER.exception('Timeout connecting {:s}'.format(str(self.__tapi_root)))
+                return False
+            except Exception:  # pylint: disable=broad-except
+                LOGGER.exception('Exception connecting {:s}'.format(str(self.__tapi_root)))
+                return False
+            else:
+                self.__started.set()
+                return True
+
+    def Disconnect(self) -> bool:
+        with self.__lock:
+            self.__terminate.set()
+            return True
+
+    def GetInitialConfig(self) -> List[Tuple[str, Any]]:
+        with self.__lock:
+            return []
+
+    def GetConfig(self, resource_keys : List[str] = []) -> List[Tuple[str, Union[Any, None, Exception]]]:
+        chk_type('resources', resource_keys, list)
+        results = []
+        with self.__lock:
+            if len(resource_keys) == 0: resource_keys = ALL_RESOURCE_KEYS
+            for i, resource_key in enumerate(resource_keys):
+                str_resource_name = 'resource_key[#{:d}]'.format(i)
+                chk_string(str_resource_name, resource_key, allow_empty=False)
+                results.extend(config_getter(self.__tapi_root, resource_key, self.__timeout))
+        return results
+
+
+    def SetConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
+        results = []
+        if len(resources) == 0:
+            return results
+        with self.__lock:
+            for resource in resources:
+                LOGGER.info('resource = {:s}'.format(str(resource)))
+
+                node_id_src = find_key(resource, 'node_id_src')
+                tp_id_src = find_key(resource, 'tp_id_src')
+                node_id_dst = find_key(resource, 'node_id_dst')
+                tp_id_dst = find_key(resource, 'tp_id_dst')
+                vlan_id = find_key(resource, 'vlan_id')
+                uuid = find_key(resource, 'uuid')
+
+                data = create_connectivity_service(
+                    self.__tapi_root, self.__timeout, uuid, node_id_src, tp_id_src, node_id_dst, tp_id_dst, vlan_id)
+                results.extend(data)
+        return results
+
+
+    def DeleteConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
+        results = []
+        if len(resources) == 0: return results
+        with self.__lock:
+            for resource in resources:
+                LOGGER.info('resource = {:s}'.format(str(resource)))
+                uuid = find_key(resource, 'uuid')
+                results.extend(delete_connectivity_service(self.__tapi_root, self.__timeout, uuid))
+        return results
+
+    def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
+        # TODO: TAPI does not support monitoring by now
+        return [False for _ in subscriptions]
+
+    def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
+        # TODO: TAPI does not support monitoring by now
+        return [False for _ in subscriptions]
+
+    def GetState(
+        self, blocking=False, terminate : Optional[threading.Event] = None
+    ) -> Iterator[Tuple[float, str, Any]]:
+        # TODO: TAPI does not support monitoring by now
+        return []
diff --git a/src/device/service/drivers/microwave/Tools.py b/src/device/service/drivers/microwave/Tools.py
new file mode 100644
index 000000000..6398b6867
--- /dev/null
+++ b/src/device/service/drivers/microwave/Tools.py
@@ -0,0 +1,177 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json, logging, requests
+from device.service.driver_api._Driver import RESOURCE_ENDPOINTS
+
+LOGGER = logging.getLogger(__name__)
+
+
+def find_key(resource, key):
+    return json.loads(resource[1])[key]
+
+# this function exports only the endpoints which are not already involved in a microwave physical link
+def isAnExportableEndpoint(node, termination_point_id, links):
+    # for each link we check if the endpoint (termination_point_id) is already used by an existing link
+    for link in links:
+        src = link['source']
+        dest = link['destination']
+        if dest['dest-node'] == node and dest['dest-tp'] == termination_point_id:
+            return False
+        elif src['source-node'] == node and src['source-tp'] == termination_point_id:
+            return False
+
+    return True
+
+def config_getter(root_url, resource_key, timeout):
+    # getting endpoints
+    url = '{:s}/nmswebs/restconf/data/ietf-network:networks/network=SIAE-ETH-TOPOLOGY?fields=ietf-network-topology:link(link-id;destination(dest-node;dest-tp);source(source-node;source-tp));node(node-id;ietf-network-topology:termination-point(tp-id;ietf-te-topology:te/name)))'.format(root_url)
+    result = []
+    try:
+        response = requests.get(url, timeout=timeout, verify=False)
+    except requests.exceptions.Timeout:
+        LOGGER.exception('Timeout connecting {:s}'.format(url))
+    except Exception as e:  # pylint: disable=broad-except
+        LOGGER.exception('Exception retrieving {:s}'.format(resource_key))
+        result.append((resource_key, e))
+    else:
+        context = json.loads(response.content)
+    
+
+        if resource_key == RESOURCE_ENDPOINTS:
+            if not (context.get('ietf-network:network') is None):
+                network_instance = context['ietf-network:network']
+                if not (network_instance.get('ietf-network-topology:link') is None):
+                    links = network_instance['ietf-network-topology:link']  
+
+                    for sip in network_instance['node']:
+                        tp = sip['ietf-network-topology:termination-point']
+                        node_id = sip['node-id']
+                        for te in tp:
+                            tp_id = te['tp-id']
+                            if isAnExportableEndpoint(node_id, tp_id, links):
+                                result.append(('/endpoints/endpoint[{:s}:{:s}]'.format(node_id,tp_id), {'uuid': tp_id, 'type': te['ietf-te-topology:te']['name']}))
+
+    # getting created services 
+    url = '{:s}/nmswebs/restconf/data/ietf-eth-tran-service:etht-svc'.format(root_url)
+    try:
+        response = requests.get(url, timeout=timeout, verify=False)
+    except requests.exceptions.Timeout:
+        LOGGER.exception('Timeout connecting {:s}'.format(url))
+    except Exception as e:  # pylint: disable=broad-except
+        LOGGER.exception('Exception retrieving {:s}'.format(resource_key))
+        result.append((resource_key, e))
+    else:
+        context = json.loads(response.content)
+    
+
+        if resource_key == RESOURCE_ENDPOINTS:
+            if not (context.get('ietf-eth-tran-service:etht-svc') is None):
+                etht_service = context['ietf-eth-tran-service:etht-svc']
+                if not (etht_service.get('etht-svc-instances') is None):
+                    service_instances = etht_service['etht-svc-instances'] 
+            
+                    for service in service_instances:
+                        service_name = service['etht-svc-name']
+                        result.append(('/services/service[{:s}]'.format(service_name), {'uuid': service_name, 'type': service['etht-svc-type']}))
+            
+    return result
+
+
+def create_connectivity_service(
+    root_url, timeout, uuid, node_id_src, tp_id_src, node_id_dst, tp_id_dst, vlan_id):
+
+    url = '{:s}/nmswebs/restconf/data/ietf-eth-tran-service:etht-svc'.format(root_url)
+    headers = {'content-type': 'application/json'}
+    data = {}
+    
+    data = {
+            "etht-svc-instances": 
+            [
+	            {
+		            "etht-svc-name": uuid,
+		            "etht-svc-type": "ietf-eth-tran-types:p2p-svc",
+		            "etht-svc-end-points": 
+                    [
+		                {
+			                "etht-svc-access-points": 
+                            [
+			                    {       
+			                        "access-node-id": node_id_src,
+			                        "access-ltp-id": tp_id_src,
+			                        "access-point-id": "1"
+			                    }
+			                ],
+		                    "outer-tag": 
+                                {
+			                        "vlan-value": vlan_id,
+			                        "tag-type": "ietf-eth-tran-types:classify-c-vlan"
+		                        },
+		                    "etht-svc-end-point-name": node_id_src+':'+str(tp_id_src),
+		                    "service-classification-type": "ietf-eth-tran-types:vlan-classification"
+		                },
+		                {
+		                    "etht-svc-access-points": 
+                            [
+		                        {
+			                        "access-node-id": node_id_dst,
+			                        "access-ltp-id": tp_id_dst,
+			                        "access-point-id": "2"
+		                        }
+		                    ],
+		                    "outer-tag": 
+                                {
+			                        "vlan-value": vlan_id,
+			                        "tag-type": "ietf-eth-tran-types:classify-c-vlan"
+		                        },
+		                    "etht-svc-end-point-name": node_id_dst+':'+str(tp_id_dst),
+		                    "service-classification-type": "ietf-eth-tran-types:vlan-classification"
+		                }
+		            ]	
+	            }
+	        ]       
+           }
+
+    
+    results = []
+    try:
+        LOGGER.info('Connectivity service {:s}: {:s}'.format(str(uuid), str(data)))
+        response = requests.post(url=url, data=json.dumps(data), timeout=timeout, headers=headers, verify=False)
+        LOGGER.info('Microwave Driver response: {:s}'.format(str(response)))
+    except Exception as e:  # pylint: disable=broad-except
+        LOGGER.exception('Exception creating ConnectivityService(uuid={:s}, data={:s})'.format(str(uuid), str(data)))
+        results.append(e)
+    else:
+        if response.status_code != 201:
+            msg = 'Could not create ConnectivityService(uuid={:s}, data={:s}). status_code={:s} reply={:s}'
+            LOGGER.error(msg.format(str(uuid), str(data), str(response.status_code), str(response)))
+        results.append(response.status_code == 201)
+    return results
+
+
+def delete_connectivity_service(root_url, timeout, uuid):
+    url = '{:s}/nmswebs/restconf/data/ietf-eth-tran-service:etht-svc/etht-svc-instances={:s}'
+    url = url.format(root_url, uuid)
+    results = []
+    try:
+        response = requests.delete(url=url, timeout=timeout, verify=False)
+    except Exception as e:  # pylint: disable=broad-except
+        LOGGER.exception('Exception deleting ConnectivityService(uuid={:s})'.format(str(uuid)))
+        results.append(e)
+    else:
+        if response.status_code != 201:
+            msg = 'Could not delete ConnectivityService(uuid={:s}). status_code={:s} reply={:s}'
+            LOGGER.error(msg.format(str(uuid), str(response.status_code), str(response)))
+        results.append(response.status_code == 202)
+    return results
diff --git a/src/device/service/drivers/microwave/__init__.py b/src/device/service/drivers/microwave/__init__.py
new file mode 100644
index 000000000..925746998
--- /dev/null
+++ b/src/device/service/drivers/microwave/__init__.py
@@ -0,0 +1,27 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from device.service.driver_api._Driver import RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES
+
+ALL_RESOURCE_KEYS = [
+    RESOURCE_ENDPOINTS,
+    RESOURCE_INTERFACES,
+    RESOURCE_NETWORK_INSTANCES,
+]
+
+RESOURCE_KEY_MAPPINGS = {
+    RESOURCE_ENDPOINTS        : 'component',
+    RESOURCE_INTERFACES       : 'interface',
+    RESOURCE_NETWORK_INSTANCES: 'network_instance',
+}
diff --git a/src/device/tests/Device_Microwave_Template.py b/src/device/tests/Device_Microwave_Template.py
new file mode 100644
index 000000000..1f2d57a1d
--- /dev/null
+++ b/src/device/tests/Device_Microwave_Template.py
@@ -0,0 +1,46 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from common.tools.object_factory.ConfigRule import json_config_rule_delete, json_config_rule_set
+from common.tools.object_factory.Device import (
+    json_device_connect_rules, json_device_id, json_device_microwave_disabled)
+
+DEVICE_MICROWAVE_UUID    = 'DEVICE-MICROWAVE'     # populate 'device-uuid' of the MICROWAVE SMDC server
+DEVICE_MICROWAVE_ADDRESS = '127.0.0.1'       # populate 'address' of the MICROWAVE SMDC server
+DEVICE_MICROWAVE_PORT    = 8443                   # populate 'port' of the MICROWAVE SMDC server
+DEVICE_MICROWAVE_TIMEOUT = 120                    # populate 'timeout' of the MICROWAVE SMDC server
+
+DEVICE_MICROWAVE_ID = json_device_id(DEVICE_MICROWAVE_UUID)
+DEVICE_MICROWAVE    = json_device_microwave_disabled(DEVICE_MICROWAVE_UUID)
+
+DEVICE_MICROWAVE_CONNECT_RULES = json_device_connect_rules(DEVICE_MICROWAVE_ADDRESS, DEVICE_MICROWAVE_PORT, {
+    'timeout' : DEVICE_MICROWAVE_TIMEOUT,
+})
+
+DEVICE_MICROWAVE_CONFIG_RULES = [
+    json_config_rule_set('/services/service[service_uuid]', {
+        'uuid'                      : 'service-uuid',       # populate 'service_name of the service to test
+        'node_id_src'               : '172.26.60.243',      # populate 'node_id_src' of the service to test
+        'tp_id_src'                 : 9,                    # populate 'tp_id_src' of the service to test
+        'node_id_dst'               : '172.26.60.244',      # populate 'node_id_dst' of the service to test
+        'tp_id_dst'                 : 9,                    # populate 'tp_id_dst' of the service to test
+        'vlan_id'                   : 121,                  # populate 'vlan_id' of the service to test
+    })
+]
+
+DEVICE_MICROWAVE_DECONFIG_RULES = [
+    json_config_rule_delete('/services/service[service-uuid]', {
+        'uuid': 'service-uuid'                              # populate 'service_name' of the service to test
+    })
+]
diff --git a/src/device/tests/test_unitary_microwave.py b/src/device/tests/test_unitary_microwave.py
new file mode 100644
index 000000000..8718d99fb
--- /dev/null
+++ b/src/device/tests/test_unitary_microwave.py
@@ -0,0 +1,316 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import calendar, copy, dateutil.parser, grpc, json, logging, operator, os, pytest, queue, time
+from datetime import datetime, timezone
+from typing import Tuple
+from common.orm.Database import Database
+from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
+from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
+from common.message_broker.MessageBroker import MessageBroker
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id
+from context.Config import (
+    GRPC_SERVICE_PORT as CONTEXT_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as CONTEXT_GRPC_MAX_WORKERS,
+    GRPC_GRACE_PERIOD as CONTEXT_GRPC_GRACE_PERIOD)
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import DeviceId, DeviceOperationalStatusEnum
+from context.service.grpc_server.ContextService import ContextService
+from device.Config import (
+    GRPC_SERVICE_PORT as DEVICE_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as DEVICE_GRPC_MAX_WORKERS,
+    GRPC_GRACE_PERIOD as DEVICE_GRPC_GRACE_PERIOD)
+from device.client.DeviceClient import DeviceClient
+from device.proto.context_pb2 import ConfigActionEnum, Context, Device, Topology
+from device.proto.device_pb2 import MonitoringSettings
+from device.proto.kpi_sample_types_pb2 import KpiSampleType
+from device.service.DeviceService import DeviceService
+from device.service.driver_api._Driver import _Driver
+from device.service.driver_api.DriverFactory import DriverFactory
+from device.service.driver_api.DriverInstanceCache import DriverInstanceCache
+from device.service.drivers import DRIVERS
+from device.tests.MockMonitoringService import MockMonitoringService
+from monitoring.Config import (
+    GRPC_SERVICE_PORT as MONITORING_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as MONITORING_GRPC_MAX_WORKERS,
+    GRPC_GRACE_PERIOD as MONITORING_GRPC_GRACE_PERIOD)
+from monitoring.client.monitoring_client import MonitoringClient
+from .CommonObjects import CONTEXT, TOPOLOGY
+
+from .Device_Emulated import (
+    DEVICE_EMU, DEVICE_EMU_CONFIG_ADDRESSES, DEVICE_EMU_CONFIG_ENDPOINTS, DEVICE_EMU_CONNECT_RULES,
+    DEVICE_EMU_DECONFIG_ADDRESSES, DEVICE_EMU_DECONFIG_ENDPOINTS, DEVICE_EMU_EP_DESCS, DEVICE_EMU_ENDPOINTS_COOKED,
+    DEVICE_EMU_ID, DEVICE_EMU_RECONFIG_ADDRESSES, DEVICE_EMU_UUID)
+ENABLE_EMULATED = True
+
+try:
+    from .Device_OpenConfig_Infinera1 import(
+    #from .Device_OpenConfig_Infinera2 import(
+        DEVICE_OC, DEVICE_OC_CONFIG_RULES, DEVICE_OC_DECONFIG_RULES, DEVICE_OC_CONNECT_RULES, DEVICE_OC_ID,
+        DEVICE_OC_UUID)
+    ENABLE_OPENCONFIG = True
+except ImportError:
+    ENABLE_OPENCONFIG = False
+
+try:
+    from .Device_Transport_Api_CTTC import (
+        DEVICE_TAPI, DEVICE_TAPI_CONNECT_RULES, DEVICE_TAPI_UUID, DEVICE_TAPI_ID, DEVICE_TAPI_CONFIG_RULES,
+        DEVICE_TAPI_DECONFIG_RULES)
+    ENABLE_TAPI = True
+except ImportError:
+    ENABLE_TAPI = False
+
+try:
+    from .Device_Microwave_Template import (
+        DEVICE_MICROWAVE, DEVICE_MICROWAVE_CONNECT_RULES, DEVICE_MICROWAVE_UUID, DEVICE_MICROWAVE_ID, DEVICE_MICROWAVE_CONFIG_RULES,
+        DEVICE_MICROWAVE_DECONFIG_RULES)
+    ENABLE_MICROWAVE = True
+except ImportError as error:
+    ENABLE_MICROWAVE = False
+    print(error.__class__.__name__ + ": " + error.message)
+
+from .mock_p4runtime_service import MockP4RuntimeService
+try:
+    from .device_p4 import(
+        DEVICE_P4, DEVICE_P4_ID, DEVICE_P4_UUID, DEVICE_P4_NAME, DEVICE_P4_ADDRESS, DEVICE_P4_PORT, DEVICE_P4_WORKERS,
+        DEVICE_P4_GRACE_PERIOD, DEVICE_P4_CONNECT_RULES, DEVICE_P4_CONFIG_RULES)
+    ENABLE_P4 = True
+except ImportError:
+    ENABLE_P4 = False
+
+#ENABLE_EMULATED   = False # set to False to disable tests of Emulated devices
+#ENABLE_OPENCONFIG = False # set to False to disable tests of OpenConfig devices
+#ENABLE_TAPI       = False # set to False to disable tests of TAPI devices
+#ENABLE_P4         = False # set to False to disable tests of P4 devices
+
+ENABLE_OPENCONFIG_CONFIGURE   = True
+ENABLE_OPENCONFIG_MONITOR     = True
+ENABLE_OPENCONFIG_DECONFIGURE = True
+
+
+logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING)
+logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING)
+logging.getLogger('monitoring-client').setLevel(logging.WARNING)
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+CONTEXT_GRPC_SERVICE_PORT = 10000 + CONTEXT_GRPC_SERVICE_PORT # avoid privileged ports
+DEVICE_GRPC_SERVICE_PORT = 10000 + DEVICE_GRPC_SERVICE_PORT # avoid privileged ports
+MONITORING_GRPC_SERVICE_PORT = 10000 + MONITORING_GRPC_SERVICE_PORT # avoid privileged ports
+
+DEFAULT_REDIS_SERVICE_HOST = '127.0.0.1'
+DEFAULT_REDIS_SERVICE_PORT = 6379
+DEFAULT_REDIS_DATABASE_ID  = 0
+
+REDIS_CONFIG = {
+    'REDIS_SERVICE_HOST': os.environ.get('REDIS_SERVICE_HOST', DEFAULT_REDIS_SERVICE_HOST),
+    'REDIS_SERVICE_PORT': os.environ.get('REDIS_SERVICE_PORT', DEFAULT_REDIS_SERVICE_PORT),
+    'REDIS_DATABASE_ID' : os.environ.get('REDIS_DATABASE_ID',  DEFAULT_REDIS_DATABASE_ID ),
+}
+
+SCENARIOS = [
+    ('all_inmemory', DatabaseBackendEnum.INMEMORY, {},           MessageBrokerBackendEnum.INMEMORY, {}          ),
+    #('all_redis',    DatabaseBackendEnum.REDIS,    REDIS_CONFIG, MessageBrokerBackendEnum.REDIS,    REDIS_CONFIG),
+]
+
+@pytest.fixture(scope='session', ids=[str(scenario[0]) for scenario in SCENARIOS], params=SCENARIOS)
+def context_db_mb(request) -> Tuple[Database, MessageBroker]:
+    name,db_backend,db_settings,mb_backend,mb_settings = request.param
+    msg = 'Running scenario {:s} db_backend={:s}, db_settings={:s}, mb_backend={:s}, mb_settings={:s}...'
+    LOGGER.info(msg.format(str(name), str(db_backend.value), str(db_settings), str(mb_backend.value), str(mb_settings)))
+    _database = Database(get_database_backend(backend=db_backend, **db_settings))
+    _message_broker = MessageBroker(get_messagebroker_backend(backend=mb_backend, **mb_settings))
+    yield _database, _message_broker
+    _message_broker.terminate()
+
+@pytest.fixture(scope='session')
+def context_service(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
+    _service = ContextService(
+        context_db_mb[0], context_db_mb[1], port=CONTEXT_GRPC_SERVICE_PORT, max_workers=CONTEXT_GRPC_MAX_WORKERS,
+        grace_period=CONTEXT_GRPC_GRACE_PERIOD)
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def context_client(context_service : ContextService): # pylint: disable=redefined-outer-name
+    _client = ContextClient(address='127.0.0.1', port=CONTEXT_GRPC_SERVICE_PORT)
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def monitoring_service():
+    _service = MockMonitoringService(port=MONITORING_GRPC_SERVICE_PORT, max_workers=MONITORING_GRPC_MAX_WORKERS,
+        grace_period=MONITORING_GRPC_GRACE_PERIOD)
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def monitoring_client(monitoring_service : MockMonitoringService): # pylint: disable=redefined-outer-name
+    _client = MonitoringClient(server='127.0.0.1', port=MONITORING_GRPC_SERVICE_PORT)
+    #yield _client
+    #_client.close()
+    return _client
+
+@pytest.fixture(scope='session')
+def device_service(
+    context_client : ContextClient,         # pylint: disable=redefined-outer-name
+    monitoring_client : MonitoringClient):  # pylint: disable=redefined-outer-name
+
+    _driver_factory = DriverFactory(DRIVERS)
+    _driver_instance_cache = DriverInstanceCache(_driver_factory)
+    _service = DeviceService(
+        context_client, monitoring_client, _driver_instance_cache, port=DEVICE_GRPC_SERVICE_PORT,
+        max_workers=DEVICE_GRPC_MAX_WORKERS, grace_period=DEVICE_GRPC_GRACE_PERIOD)
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def device_client(device_service : DeviceService): # pylint: disable=redefined-outer-name
+    _client = DeviceClient(address='127.0.0.1', port=DEVICE_GRPC_SERVICE_PORT)
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def p4runtime_service():
+    _service = MockP4RuntimeService(
+        address=DEVICE_P4_ADDRESS, port=DEVICE_P4_PORT,
+        max_workers=DEVICE_P4_WORKERS,
+        grace_period=DEVICE_P4_GRACE_PERIOD)
+    _service.start()
+    yield _service
+    _service.stop()
+
+
+def test_prepare_environment(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    context_client.SetContext(Context(**CONTEXT))
+    context_client.SetTopology(Topology(**TOPOLOGY))
+
+
+
+
+# ----- Test Device Driver Microwave ------------------------------------------------
+
+def test_device_microwave_add_correct(
+    device_client: DeviceClient,        # pylint: disable=redefined-outer-name
+    device_service: DeviceService):     # pylint: disable=redefined-outer-name
+
+    if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No MICROWAVE device has been configured')
+    
+    DEVICE_MICROWAVE_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_MICROWAVE)
+    DEVICE_MICROWAVE_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_MICROWAVE_CONNECT_RULES)
+    device_client.AddDevice(Device(**DEVICE_MICROWAVE_WITH_CONNECT_RULES))
+    driver: _Driver = device_service.driver_instance_cache.get(DEVICE_MICROWAVE_UUID)
+    assert driver is not None
+
+
+def test_device_microwave_get(
+    context_client: ContextClient,      # pylint: disable=redefined-outer-name
+    device_client: DeviceClient):       # pylint: disable=redefined-outer-name
+
+    if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No MICROWAVE device has been configured')
+
+    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_MICROWAVE_ID))
+    LOGGER.info('initial_config = {:s}'.format(grpc_message_to_json_string(initial_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_MICROWAVE_ID))
+    LOGGER.info('device_data = {:s}'.format(grpc_message_to_json_string(device_data)))
+
+
+def test_device_microwave_configure(
+    context_client: ContextClient,      # pylint: disable=redefined-outer-name
+    device_client: DeviceClient,        # pylint: disable=redefined-outer-name
+    device_service: DeviceService):     # pylint: disable=redefined-outer-name
+
+    if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No MICROWAVE device has been configured')
+
+    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_MICROWAVE_UUID)
+    assert driver is not None
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    DEVICE_MICROWAVE_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_MICROWAVE)
+    DEVICE_MICROWAVE_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_MICROWAVE_CONFIG_RULES)
+    device_client.ConfigureDevice(Device(**DEVICE_MICROWAVE_WITH_CONFIG_RULES))
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_MICROWAVE_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+    for config_rule in DEVICE_MICROWAVE_CONFIG_RULES:
+        #import pdb;
+        #pdb. set_trace()
+        config_rule = (
+            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value'])
+        assert config_rule in config_rules
+
+
+def test_device_microwave_deconfigure(
+    context_client: ContextClient,      # pylint: disable=redefined-outer-name
+    device_client: DeviceClient,        # pylint: disable=redefined-outer-name
+    device_service: DeviceService):     # pylint: disable=redefined-outer-name
+
+    if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No MICROWAVE device has been configured')
+
+    driver: _Driver = device_service.driver_instance_cache.get(DEVICE_MICROWAVE_UUID)
+    assert driver is not None
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    DEVICE_MICROWAVE_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_MICROWAVE)
+    DEVICE_MICROWAVE_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_MICROWAVE_DECONFIG_RULES)
+    device_client.ConfigureDevice(Device(**DEVICE_MICROWAVE_WITH_DECONFIG_RULES))
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_MICROWAVE_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+    for config_rule in DEVICE_MICROWAVE_DECONFIG_RULES:
+        action_set = ConfigActionEnum.Name(ConfigActionEnum.CONFIGACTION_SET)
+        config_rule = (action_set, config_rule['resource_key'], config_rule['resource_value'])
+        assert config_rule not in config_rules
+
+
+def test_device_microwave_delete(
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No MICROWAVE device has been configured')
+
+    device_client.DeleteDevice(DeviceId(**DEVICE_MICROWAVE_ID))
+    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_MICROWAVE_UUID, {})
+    assert driver is None
\ No newline at end of file
-- 
GitLab


From 7a84ea8d65b8c7b9c898e2148f1275eb0cee4e1b Mon Sep 17 00:00:00 2001
From: Roberto Rubino <roberto.rubino@siaemic.com>
Date: Mon, 16 May 2022 15:46:16 +0000
Subject: [PATCH 05/60] double checked name of variable __ietf_root

---
 .../service/drivers/microwave/IETFApiDriver.py     | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/device/service/drivers/microwave/IETFApiDriver.py b/src/device/service/drivers/microwave/IETFApiDriver.py
index 714a149b6..0f68445f2 100644
--- a/src/device/service/drivers/microwave/IETFApiDriver.py
+++ b/src/device/service/drivers/microwave/IETFApiDriver.py
@@ -26,20 +26,20 @@ class IETFApiDriver(_Driver):
         self.__lock = threading.Lock()
         self.__started = threading.Event()
         self.__terminate = threading.Event()
-        self.__tapi_root = 'https://' + address + ':' + str(port)
+        self.__ietf_root = 'https://' + address + ':' + str(port)
         self.__timeout = int(settings.get('timeout', 120))
 
     def Connect(self) -> bool:
-        url = self.__tapi_root + '/nmswebs/restconf/data/ietf-network:networks'
+        url = self.__ietf_root + '/nmswebs/restconf/data/ietf-network:networks'
         with self.__lock:
             if self.__started.is_set(): return True
             try:
                 requests.get(url, timeout=self.__timeout, verify=False)
             except requests.exceptions.Timeout:
-                LOGGER.exception('Timeout connecting {:s}'.format(str(self.__tapi_root)))
+                LOGGER.exception('Timeout connecting {:s}'.format(str(self.__ietf_root)))
                 return False
             except Exception:  # pylint: disable=broad-except
-                LOGGER.exception('Exception connecting {:s}'.format(str(self.__tapi_root)))
+                LOGGER.exception('Exception connecting {:s}'.format(str(self.__ietf_root)))
                 return False
             else:
                 self.__started.set()
@@ -62,7 +62,7 @@ class IETFApiDriver(_Driver):
             for i, resource_key in enumerate(resource_keys):
                 str_resource_name = 'resource_key[#{:d}]'.format(i)
                 chk_string(str_resource_name, resource_key, allow_empty=False)
-                results.extend(config_getter(self.__tapi_root, resource_key, self.__timeout))
+                results.extend(config_getter(self.__ietf_root, resource_key, self.__timeout))
         return results
 
 
@@ -82,7 +82,7 @@ class IETFApiDriver(_Driver):
                 uuid = find_key(resource, 'uuid')
 
                 data = create_connectivity_service(
-                    self.__tapi_root, self.__timeout, uuid, node_id_src, tp_id_src, node_id_dst, tp_id_dst, vlan_id)
+                    self.__ietf_root, self.__timeout, uuid, node_id_src, tp_id_src, node_id_dst, tp_id_dst, vlan_id)
                 results.extend(data)
         return results
 
@@ -94,7 +94,7 @@ class IETFApiDriver(_Driver):
             for resource in resources:
                 LOGGER.info('resource = {:s}'.format(str(resource)))
                 uuid = find_key(resource, 'uuid')
-                results.extend(delete_connectivity_service(self.__tapi_root, self.__timeout, uuid))
+                results.extend(delete_connectivity_service(self.__ietf_root, self.__timeout, uuid))
         return results
 
     def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
-- 
GitLab


From dcb44d803eb0260d16e96938c2096c23079b0f3e Mon Sep 17 00:00:00 2001
From: PabloArmingolRobles <pablo.armingolrobles.practicas@telefonica.com>
Date: Tue, 17 May 2022 12:01:50 +0200
Subject: [PATCH 06/60] Device component: - Implemented support for ACLs -
 Added suport for Candidate datastore

---
 src/device/service/driver_api/_Driver.py      |   1 +
 .../drivers/openconfig/OpenConfigDriver.py    |  36 ++++-
 .../drivers/openconfig/templates/Acl.py       | 123 ++++++++++++++++++
 .../drivers/openconfig/templates/Namespace.py |   3 +
 .../drivers/openconfig/templates/__init__.py  |   6 +-
 .../acl/acl-set/acl-entry/edit_config.xml     |  42 ++++++
 .../drivers/openconfig/templates/acl/get.xml  |   7 +
 .../acl/interfaces/egress/edit_config.xml     |  26 ++++
 .../acl/interfaces/ingress/edit_config.xml    |  26 ++++
 src/device/tests/.gitignore                   |   2 +
 src/device/tests/test_unitary.py              |   3 +
 11 files changed, 270 insertions(+), 5 deletions(-)
 create mode 100644 src/device/service/drivers/openconfig/templates/Acl.py
 create mode 100644 src/device/service/drivers/openconfig/templates/acl/acl-set/acl-entry/edit_config.xml
 create mode 100644 src/device/service/drivers/openconfig/templates/acl/get.xml
 create mode 100644 src/device/service/drivers/openconfig/templates/acl/interfaces/egress/edit_config.xml
 create mode 100644 src/device/service/drivers/openconfig/templates/acl/interfaces/ingress/edit_config.xml

diff --git a/src/device/service/driver_api/_Driver.py b/src/device/service/driver_api/_Driver.py
index f30165a17..7dbb9eddb 100644
--- a/src/device/service/driver_api/_Driver.py
+++ b/src/device/service/driver_api/_Driver.py
@@ -21,6 +21,7 @@ RESOURCE_ENDPOINTS         = '__endpoints__'
 RESOURCE_INTERFACES        = '__interfaces__'
 RESOURCE_NETWORK_INSTANCES = '__network_instances__'
 RESOURCE_ROUTING_POLICIES  = '__routing_policies__'
+RESOURCE_ACL               = '__acl__'
 
 class _Driver:
     def __init__(self, address : str, port : int, **settings) -> None:
diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index 7f582c488..e315b8442 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -31,7 +31,11 @@ from device.service.driver_api.AnyTreeTools import TreeNode, get_subnode, set_su
 from .templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filter, parse
 from .RetryDecorator import retry
 
-DEBUG_MODE = False
+
+from ncclient import manager
+
+
+DEBUG_MODE = True
 #logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
 logging.getLogger('apscheduler.executors.default').setLevel(logging.INFO if DEBUG_MODE else logging.ERROR)
 logging.getLogger('apscheduler.scheduler').setLevel(logging.INFO if DEBUG_MODE else logging.ERROR)
@@ -65,14 +69,14 @@ class NetconfSessionHandler:
         self.__netconf_session : Session = None
         self.__netconf_manager : Manager = None
 
-    def connect(self):
+    def connect(self):        
         with self.__lock:
             self.__netconf_session = connect_ssh(
                 host=self.__address, port=self.__port, username=self.__username, password=self.__password)
             self.__netconf_manager = Manager(self.__netconf_session, timeout=self.__timeout)
             self.__netconf_manager.set_logger_level(logging.DEBUG if DEBUG_MODE else logging.WARNING)
             self.__connected.set()
-
+        
     def disconnect(self):
         if not self.__connected.is_set(): return
         with self.__lock:
@@ -239,14 +243,25 @@ class OpenConfigDriver(_Driver):
                     resource_key,resource_value = resource
                     chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
                     str_config_message = compose_config(resource_key, resource_value)
+                    
+                    with manager.connect(host=address, port=830, username='admin', password='admin',
+                                    hostkey_verify=False, device_params={'name':'huaweiyang'},
+                                    look_for_keys=False, allow_agent=False) as m:
+                        assert(":candidate" in m.server_capabilities)
+                        with m.locked(target='candidate'):
+                            m.edit_config(config=str_config_message, default_operation="merge", target="candidate")
+                            m.commit()
+                            results.append(True)
+                    """
                     if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
                     LOGGER.info('[SetConfig] str_config_message[{:d}] = {:s}'.format(
                         len(str_config_message), str(str_config_message)))
                     self.__netconf_handler.edit_config(str_config_message, target='running')
                     results.append(True)
+                    """
                 except Exception as e: # pylint: disable=broad-except
                     LOGGER.exception('Exception setting {:s}: {:s}'.format(str_resource_name, str(resource)))
-                    results.append(e) # if validation fails, store the exception
+                    results.append(e) # if validation fails, store the exception         
         return results
 
     def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
@@ -264,11 +279,23 @@ class OpenConfigDriver(_Driver):
                     resource_key,resource_value = resource
                     chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
                     str_config_message = compose_config(resource_key, resource_value, delete=True)
+                    
+                    with manager.connect(host=address, port=830, username='admin', password='admin',
+                                    hostkey_verify=False, device_params={'name':'huaweiyang'},
+                                    look_for_keys=False, allow_agent=False) as m:
+                        assert(":candidate" in m.server_capabilities)
+                        with m.locked(target='candidate'):
+                            m.edit_config(config=str_config_message, default_operation="merge", target="candidate")
+                            m.commit()
+                            results.append(True)
+                    
+                    """
                     if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
                     LOGGER.info('[DeleteConfig] str_config_message[{:d}] = {:s}'.format(
                         len(str_config_message), str(str_config_message)))
                     self.__netconf_handler.edit_config(str_config_message, target='running')
                     results.append(True)
+                    """
                 except Exception as e: # pylint: disable=broad-except
                     LOGGER.exception('Exception deleting {:s}: {:s}'.format(str_resource_name, str(resource_key)))
                     results.append(e) # if validation fails, store the exception
@@ -364,3 +391,4 @@ class OpenConfigDriver(_Driver):
                 return
             if sample is None: continue
             yield sample
+            
\ No newline at end of file
diff --git a/src/device/service/drivers/openconfig/templates/Acl.py b/src/device/service/drivers/openconfig/templates/Acl.py
new file mode 100644
index 000000000..ab07fe6fd
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/Acl.py
@@ -0,0 +1,123 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import logging, lxml.etree as ET
+from typing import Any, Dict, List, Tuple
+from .Namespace import NAMESPACES
+from .Tools import add_value_from_collection, add_value_from_tag
+
+LOGGER = logging.getLogger(__name__)
+
+XPATH_ACL_SET     = "//ocacl:acl/ocacl:acl-sets/ocacl:acl-set"
+XPATH_A_ACL_ENTRY = ".//ocacl:acl-entries/ocacl:ecl-entry"
+XPATH_A_IPv4      = ".//ocacl:ipv4/ocacl:config"
+XPATH_A_TRANSPORT = ".//ocacl:transport/ocacl:config"
+XPATH_A_ACTIONS   = ".//ocacl:actions/ocacl:config"
+
+XPATH_INTERFACE         = "//ocacl:acl/ocacl:interfaces/ocacl:interface"
+XPATH_I_INGRESS         = ".//ocacl:ingress-acl-sets/ocacl:ingress-acl-set"
+XPATH_I_EGRESS          = ".//ocacl:egress-acl-sets/ocacl:egress-acl-set"
+
+def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
+    #LOGGER.info('[ACL] xml_data = {:s}'.format(str(ET.tostring(xml_data))))
+
+    response = []
+    acl = {}
+    
+    for xml_acl in xml_data.xpath(XPATH_ACL_SET, namespaces=NAMESPACES):
+        #LOGGER.info('xml_acl = {:s}'.format(str(ET.tostring(xml_acl))))
+
+        acl_name = xml_acl.find('ocacl:name', namespaces=NAMESPACES)
+        if acl_name is None or acl_name.text is None: continue
+        add_value_from_tag(acl, 'name', acl_name)
+
+        acl_type = xml_acl.find('ocacl:type', namespaces=NAMESPACES)
+        add_value_from_tag(acl, 'type', acl_type)
+
+        for xml_acl_entries in xml_acl.xpath(XPATH_A_ACL_ENTRY, namespaces=NAMESPACES):
+
+            acl_id = xml_acl_entries.find('ocacl:sequence_id', namespaces=NAMESPACES)
+            add_value_from_tag(acl, 'sequence_id', acl_id)
+            
+            for xml_ipv4 in xml_acl_entries.xpath(XPATH_A_IPv4, namespaces=NAMESPACES):
+
+                ipv4_source = xml_ipv4.find('ocacl:source_address', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'source_address' , ipv4_source)
+
+                ipv4_destination = xml_ipv4.find('ocacl:destination_address', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'destination_address' , ipv4_destination)
+
+                ipv4_protocol = xml_ipv4.find('ocacl:protocol', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'protocol' , ipv4_protocol)
+                
+                ipv4_dscp = xml_ipv4.find('ocacl:dscp', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'dscp' , ipv4_dscp)
+                
+                ipv4_hop_limit = xml_ipv4.find('ocacl:hop_limit', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'hop_limit' , ipv4_hop_limit)
+                
+            for xml_transport in xml_acl_entries.xpath(XPATH_A_TRANSPORT, namespaces=NAMESPACES):
+
+                transport_source = xml_transport.find('ocacl:source_port', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'source_port' ,transport_source)
+
+                transport_destination = xml_transport.find('ocacl:destination_port', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'destination_port' ,transport_destination)
+                
+                transport_tcp_flags = xml_transport.find('ocacl:tcp_flags', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'tcp_flags' ,transport_tcp_flags)
+            
+            for xml_action in xml_acl_entries.xpath(XPATH_A_ACTIONS, namespaces=NAMESPACES):
+
+                action = xml_action.find('ocacl:forwarding_action', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'forwarding_action' ,action)
+                
+                log_action = xml_action.find('ocacl:log_action', namespaces=NAMESPACES)
+                add_value_from_tag(acl, 'log_action' ,log_action)
+
+            resource_key =  '/acl/acl-set[{:s}][{:s}]/acl-entry[{:s}]'.format(
+                acl['name'], acl['type'], acl['sequence-id'])
+            response.append((resource_key,acl))
+    
+    for xml_interface in xml_data.xpath(XPATH_INTERFACE, namespaces=NAMESPACES):
+
+        interface = {}
+
+        interface_id = xml_interface.find('ocacl:id', namespaces=NAMESPACES)
+        add_value_from_tag(interface, 'id' , interface_id)
+
+        for xml_ingress in xml_interface.xpath(XPATH_I_INGRESS, namespaces=NAMESPACES):
+
+            i_name = xml_ingress.find('ocacl:set_name_ingress', namespaces=NAMESPACES)
+            add_value_from_tag(interface, 'ingress_set_name' , i_name)
+
+            i_type = xml_ingress.find('ocacl:type_ingress', namespaces=NAMESPACES)
+            add_value_from_tag(interface, 'ingress_type' , i_type)
+            
+            resource_key =  '/acl/interfaces/ingress[{:s}][{:s}]'.format(
+                acl['name'], acl['type'])
+            response.append((resource_key,interface))
+
+        for xml_egress in xml_interface.xpath(XPATH_I_EGRESS, namespaces=NAMESPACES):
+
+            e_name = xml_egress.find('ocacl:set_name_egress', namespaces=NAMESPACES)
+            add_value_from_tag(interface, 'egress_set_name' , e_name)
+
+            e_type = xml_egress.find('ocacl:type_egress', namespaces=NAMESPACES)
+            add_value_from_tag(interface, 'egress_type' , e_type)
+    
+            resource_key =  '/acl/interfaces/egress[{:s}][{:s}]'.format(
+                acl['name'], acl['type'])
+            response.append((resource_key,interface))
+    return response
diff --git a/src/device/service/drivers/openconfig/templates/Namespace.py b/src/device/service/drivers/openconfig/templates/Namespace.py
index 35be5827d..d9bdae323 100644
--- a/src/device/service/drivers/openconfig/templates/Namespace.py
+++ b/src/device/service/drivers/openconfig/templates/Namespace.py
@@ -28,8 +28,11 @@ NAMESPACE_POLICY_TYPES_2         = 'http://openconfig.net/yang/policy_types'
 NAMESPACE_ROUTING_POLICY         = 'http://openconfig.net/yang/routing-policy'
 NAMESPACE_VLAN                   = 'http://openconfig.net/yang/vlan'
 
+NAMESPACE_ACL                    = 'http://openconfig.net/yang/acl'
+
 NAMESPACES = {
     'nc'   : NAMESPACE_NETCONF,
+    'ocacl': NAMESPACE_ACL,
     'ocbp' : NAMESPACE_BGP_POLICY,
     'oci'  : NAMESPACE_INTERFACES,
     'ociip': NAMESPACE_INTERFACES_IP,
diff --git a/src/device/service/drivers/openconfig/templates/__init__.py b/src/device/service/drivers/openconfig/templates/__init__.py
index eb7842ea8..a6825ea41 100644
--- a/src/device/service/drivers/openconfig/templates/__init__.py
+++ b/src/device/service/drivers/openconfig/templates/__init__.py
@@ -16,17 +16,19 @@ import json, logging, lxml.etree as ET, re
 from typing import Any, Dict
 from jinja2 import Environment, PackageLoader, select_autoescape
 from device.service.driver_api._Driver import (
-    RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES, RESOURCE_ROUTING_POLICIES)
+    RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES, RESOURCE_ROUTING_POLICIES,RESOURCE_ACL)
 from .EndPoints import parse as parse_endpoints
 from .Interfaces import parse as parse_interfaces, parse_counters
 from .NetworkInstances import parse as parse_network_instances
 from .RoutingPolicy import parse as parse_routing_policy
+from .Acl import parse as parse_acl
 
 ALL_RESOURCE_KEYS = [
     RESOURCE_ENDPOINTS,
     RESOURCE_INTERFACES,
     RESOURCE_ROUTING_POLICIES,      # routing policies should come before network instances
     RESOURCE_NETWORK_INSTANCES,
+    RESOURCE_ACL,
 ]
 
 RESOURCE_KEY_MAPPINGS = {
@@ -34,6 +36,7 @@ RESOURCE_KEY_MAPPINGS = {
     RESOURCE_INTERFACES       : 'interface',
     RESOURCE_NETWORK_INSTANCES: 'network_instance',
     RESOURCE_ROUTING_POLICIES : 'routing_policy',
+    RESOURCE_ACL              : 'acl',
 }
 
 RESOURCE_PARSERS = {
@@ -42,6 +45,7 @@ RESOURCE_PARSERS = {
     'network_instance': parse_network_instances,
     'routing_policy'  : parse_routing_policy,
     'interfaces/interface/state/counters': parse_counters,
+    'acl'             : parse_acl,
 }
 
 LOGGER = logging.getLogger(__name__)
diff --git a/src/device/service/drivers/openconfig/templates/acl/acl-set/acl-entry/edit_config.xml b/src/device/service/drivers/openconfig/templates/acl/acl-set/acl-entry/edit_config.xml
new file mode 100644
index 000000000..fac259b6f
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/acl/acl-set/acl-entry/edit_config.xml
@@ -0,0 +1,42 @@
+<acl xmlns="http://openconfig.net/yang/acl">
+  <acl-sets>
+    <acl-set{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+      <name>{{name}}</name>
+      <type>{{type}}</type>
+      <config>
+        <name>{{name}}</name>
+        <type>{{type}}</type>
+      </config>
+      <acl-entries>
+        <acl-entry>
+          <sequence-id>{{sequence_id}}</sequence-id>
+          <config>
+            <sequence-id>{{sequence_id}}</sequence-id>
+          </config>
+          <ipv4>
+            <config>
+              {% if source_address is defined %}<source-address>{{source_address}}</source-address>{% endif%}
+              {% if destination_address is defined %}<destination-address>{{destination_address}}</destination-address>{% endif%}
+              {% if protocol is defined %}<protocol>{{protocol}}</protocol>{% endif%}
+              {% if dscp is defined %}<dscp>{{dscp}}</dscp>{% endif%}
+              {% if hop_limit is defined %}<hop-limit>{{hop_limit}}</hop-limit>{% endif%}
+            </config>
+          </ipv4>
+          <transport>
+            <config>
+              {% if source_port is defined %}<source-port>{{source_port}}</source-port>{% endif%}
+              {% if destination_port is defined %}<destination-port>{{destination_port}}</destination-port>{% endif%}
+              {% if tcp_flags is defined %}<tcp-flags>{{tcp_flags}}</tcp-flags>{% endif%}
+            </config>
+          </transport>
+          <actions>
+            <config>
+              {% if forwarding_action is defined %}<forwarding-action>{{forwarding_action}}</forwarding-action>{% endif%}
+              {% if log_action is defined %}<log-action>{{log_action}}</log-action>{% endif%}
+            </config>
+          </actions>
+        </acl-entry>
+      </acl-entries>
+    </acl-set>
+  </acl-sets>
+</acl>
diff --git a/src/device/service/drivers/openconfig/templates/acl/get.xml b/src/device/service/drivers/openconfig/templates/acl/get.xml
new file mode 100644
index 000000000..dfed16242
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/acl/get.xml
@@ -0,0 +1,7 @@
+<acl xmlns="http://openconfig.net/yang/acl">
+    <acl-sets>
+    </acl-sets>
+    <interfaces>
+    </interfaces>
+</acl>
+    
\ No newline at end of file
diff --git a/src/device/service/drivers/openconfig/templates/acl/interfaces/egress/edit_config.xml b/src/device/service/drivers/openconfig/templates/acl/interfaces/egress/edit_config.xml
new file mode 100644
index 000000000..d987b0cc4
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/acl/interfaces/egress/edit_config.xml
@@ -0,0 +1,26 @@
+<acl xmlns="http://openconfig.net/yang/acl">
+  <interfaces>
+    <interface{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+      <id>{{id}}</id>
+      <config>
+        <id>{{id}}</id>
+      </config>
+      <interface-ref>
+        <config>
+          <interface>{{interface}}</interface>
+          {% if subinterface is defined %}<subinterface>{{subinterface}}</subinterface>{% endif%}
+        </config>
+      </interface-ref>
+      <egress-acl-sets>
+        <egress-acl-set>
+          <set-name>{{set_name_egress}}</set-name>
+          <type>{{type_egress}}</type>
+          <config>
+            <set-name>{{set_name_egress}}</set-name>
+            <type>{{type_egress}}</type>
+          </config>
+        </egress-acl-set>
+      </egress-acl-sets>
+    </interface>
+  </interfaces>
+</acl>
diff --git a/src/device/service/drivers/openconfig/templates/acl/interfaces/ingress/edit_config.xml b/src/device/service/drivers/openconfig/templates/acl/interfaces/ingress/edit_config.xml
new file mode 100644
index 000000000..144a03c55
--- /dev/null
+++ b/src/device/service/drivers/openconfig/templates/acl/interfaces/ingress/edit_config.xml
@@ -0,0 +1,26 @@
+<acl xmlns="http://openconfig.net/yang/acl">
+  <interfaces>
+    <interface{% if operation is defined %} xmlns:nc="urn:ietf:params:xml:ns:netconf:base:1.0" nc:operation="{{operation}}"{% endif %}>
+      <id>{{id}}</id>
+      <config>
+        <id>{{id}}</id>
+      </config>
+      <interface-ref>
+        <config>
+          <interface>{{interface}}</interface>
+          {% if subinterface is defined %}<subinterface>{{subinterface}}</subinterface>{% endif%}
+        </config>
+      </interface-ref>
+      <ingress-acl-sets>
+        <ingress-acl-set>
+          <set-name>{{set_name_ingress}}</set-name>
+          <type>{{type_ingress}}</type>
+          <config>
+            <set-name>{{set_name_ingress}}</set-name>
+            <type>{{type_ingress}}</type>
+          </config>
+        </ingress-acl-set>
+      </ingress-acl-sets>
+    </interface>
+  </interfaces>
+</acl>
diff --git a/src/device/tests/.gitignore b/src/device/tests/.gitignore
index b5f6bc13b..4cbf5059c 100644
--- a/src/device/tests/.gitignore
+++ b/src/device/tests/.gitignore
@@ -1,3 +1,5 @@
 # Add here your files containing confidential testbed details such as IP addresses, ports, usernames, passwords, etc.
+Device_OpenConfig_Adva*
+Device_OpenConfig_Cisco*
 Device_OpenConfig_Infinera*
 Device_Transport_Api*
diff --git a/src/device/tests/test_unitary.py b/src/device/tests/test_unitary.py
index 411cbba05..0853da9a5 100644
--- a/src/device/tests/test_unitary.py
+++ b/src/device/tests/test_unitary.py
@@ -55,6 +55,9 @@ ENABLE_EMULATED = True
 try:
     from .Device_OpenConfig_Infinera1 import(
     #from .Device_OpenConfig_Infinera2 import(
+    #from .Device_OpenConfig_Cisco import(
+    #from .Device_OpenConfig_Adva import(
+
         DEVICE_OC, DEVICE_OC_CONFIG_RULES, DEVICE_OC_DECONFIG_RULES, DEVICE_OC_CONNECT_RULES, DEVICE_OC_ID,
         DEVICE_OC_UUID)
     ENABLE_OPENCONFIG = True
-- 
GitLab


From f5199c4c2311f1304f12a559d234a2bb85b1d541 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Tue, 17 May 2022 14:45:57 +0200
Subject: [PATCH 07/60] Device component: - OpenConfigDriver migrate from
 netconf_client to ncclient library - Clean integration of Candidate datastore
 - OpenConfigDriver code cleanup

---
 src/device/requirements.in                    |   2 +-
 .../drivers/openconfig/OpenConfigDriver.py    | 169 +++++++++---------
 .../drivers/openconfig/templates/Acl.py       |  30 ++--
 .../drivers/openconfig/templates/Namespace.py |   5 +-
 .../openconfig/templates/RoutingPolicy.py     |   2 +-
 5 files changed, 106 insertions(+), 102 deletions(-)

diff --git a/src/device/requirements.in b/src/device/requirements.in
index dde08cf19..3bac91e71 100644
--- a/src/device/requirements.in
+++ b/src/device/requirements.in
@@ -4,7 +4,7 @@ fastcache==1.1.0
 grpcio==1.43.0
 grpcio-health-checking==1.43.0
 Jinja2==3.0.3
-netconf-client==2.0.0 #1.7.3
+ncclient==0.6.13
 p4runtime==1.3.0
 paramiko==2.9.2
 prometheus-client==0.13.0
diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index e315b8442..741142363 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -20,8 +20,7 @@ from apscheduler.executors.pool import ThreadPoolExecutor
 from apscheduler.job import Job
 from apscheduler.jobstores.memory import MemoryJobStore
 from apscheduler.schedulers.background import BackgroundScheduler
-from netconf_client.connect import connect_ssh, Session
-from netconf_client.ncclient import Manager
+from ncclient.manager import Manager, connect_ssh
 from common.tools.client.RetryDecorator import delay_exponential
 from common.type_checkers.Checkers import chk_length, chk_string, chk_type, chk_float
 from device.service.driver_api.Exceptions import UnsupportedResourceKeyException
@@ -32,11 +31,9 @@ from .templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filt
 from .RetryDecorator import retry
 
 
-from ncclient import manager
-
-
 DEBUG_MODE = True
-#logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
+logging.getLogger('ncclient.manager').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
+logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
 logging.getLogger('apscheduler.executors.default').setLevel(logging.INFO if DEBUG_MODE else logging.ERROR)
 logging.getLogger('apscheduler.scheduler').setLevel(logging.INFO if DEBUG_MODE else logging.ERROR)
 logging.getLogger('monitoring-client').setLevel(logging.INFO if DEBUG_MODE else logging.ERROR)
@@ -63,29 +60,41 @@ class NetconfSessionHandler:
         self.__connected = threading.Event()
         self.__address = address
         self.__port = int(port)
-        self.__username = settings.get('username')
-        self.__password = settings.get('password')
-        self.__timeout = int(settings.get('timeout', 120))
-        self.__netconf_session : Session = None
-        self.__netconf_manager : Manager = None
-
-    def connect(self):        
+        self.__username       = settings.get('username')
+        self.__password       = settings.get('password')
+        self.__key_filename   = settings.get('key_filename')
+        self.__hostkey_verify = settings.get('hostkey_verify')
+        self.__look_for_keys  = settings.get('look_for_keys')
+        self.__allow_agent    = settings.get('allow_agent')
+        self.__force_running  = settings.get('force_running', False)
+        self.__device_params  = settings.get('device_params')
+        self.__manager_params = settings.get('manager_params')
+        self.__nc_params      = settings.get('nc_params')
+        self.__manager : Manager   = None
+        self.__candidate_supported = False
+
+    def connect(self):
         with self.__lock:
-            self.__netconf_session = connect_ssh(
-                host=self.__address, port=self.__port, username=self.__username, password=self.__password)
-            self.__netconf_manager = Manager(self.__netconf_session, timeout=self.__timeout)
-            self.__netconf_manager.set_logger_level(logging.DEBUG if DEBUG_MODE else logging.WARNING)
+            self.__manager = connect_ssh(
+                host=self.__address, port=self.__port, username=self.__username, password=self.__password,
+                device_params=self.__device_params, manager_params=self.__manager_params, nc_params=self.__nc_params,
+                key_filename=self.__key_filename, hostkey_verify=self.__hostkey_verify, allow_agent=self.__allow_agent,
+                look_for_keys=self.__look_for_keys)
+            self.__candidate_supported = ':candidate' in self.__manager.server_capabilities
             self.__connected.set()
-        
+
     def disconnect(self):
         if not self.__connected.is_set(): return
         with self.__lock:
-            self.__netconf_manager.close_session()
+            self.__manager.close_session()
+
+    @property
+    def use_candidate(self): return self.__candidate_supported and not self.__force_running
 
     @RETRY_DECORATOR
     def get(self, filter=None, with_defaults=None): # pylint: disable=redefined-builtin
         with self.__lock:
-            return self.__netconf_manager.get(filter=filter, with_defaults=with_defaults)
+            return self.__manager.get(filter=filter, with_defaults=with_defaults)
 
     @RETRY_DECORATOR
     def edit_config(
@@ -94,10 +103,16 @@ class NetconfSessionHandler:
     ):
         if config == EMPTY_CONFIG: return
         with self.__lock:
-            self.__netconf_manager.edit_config(
+            self.__manager.edit_config(
                 config, target=target, default_operation=default_operation, test_option=test_option,
                 error_option=error_option, format=format)
 
+    def locked(self, target):
+        return self.__manager.locked(target=target)
+
+    def commit(self, confirmed=False, timeout=None, persist=None, persist_id=None):
+        return self.__manager.commit(confirmed=confirmed, timeout=timeout, persist=persist, persist_id=persist_id)
+
 def compute_delta_sample(previous_sample, previous_timestamp, current_sample, current_timestamp):
     if previous_sample is None: return None
     if previous_timestamp is None: return None
@@ -166,6 +181,36 @@ def do_sampling(samples_cache : SamplesCache, resource_key : str, out_samples :
     except: # pylint: disable=bare-except
         LOGGER.exception('Error retrieving samples')
 
+def edit_config(
+    netconf_handler : NetconfSessionHandler, resources : List[Tuple[str, Any]], delete=False, target='running',
+    default_operation='merge', test_option=None, error_option=None, format='xml' # pylint: disable=redefined-builtin
+):
+    str_method = 'DeleteConfig' if delete else 'SetConfig'
+    LOGGER.info('[{:s}] resources = {:s}'.format(str_method, str(resources)))
+    results = [None for _ in resources]
+    for i,resource in enumerate(resources):
+        str_resource_name = 'resources[#{:d}]'.format(i)
+        try:
+            LOGGER.info('[{:s}] resource = {:s}'.format(str_method, str(resource)))
+            chk_type(str_resource_name, resource, (list, tuple))
+            chk_length(str_resource_name, resource, min_length=2, max_length=2)
+            resource_key,resource_value = resource
+            chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
+            str_config_message = compose_config(resource_key, resource_value, delete=delete)
+            if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
+            LOGGER.info('[{:s}] str_config_message[{:d}] = {:s}'.format(
+                str_method, len(str_config_message), str(str_config_message)))
+            netconf_handler.edit_config(
+                config=str_config_message, target=target, default_operation=default_operation,
+                test_option=test_option, error_option=error_option, format=format)
+            results[i] = True
+        except Exception as e: # pylint: disable=broad-except
+            str_operation = 'preparing' if target == 'candidate' else ('deleting' if delete else 'setting')
+            msg = '[{:s}] Exception {:s} {:s}: {:s}'
+            LOGGER.exception(msg.format(str_method, str_operation, str_resource_name, str(resource)))
+            results[i] = e # if validation fails, store the exception
+    return results
+
 class OpenConfigDriver(_Driver):
     def __init__(self, address : str, port : int, **settings) -> None: # pylint: disable=super-init-not-called
         self.__lock = threading.Lock()
@@ -231,74 +276,34 @@ class OpenConfigDriver(_Driver):
     def SetConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
         chk_type('resources', resources, list)
         if len(resources) == 0: return []
-        results = []
-        LOGGER.info('[SetConfig] resources = {:s}'.format(str(resources)))
         with self.__lock:
-            for i,resource in enumerate(resources):
-                str_resource_name = 'resources[#{:d}]'.format(i)
-                try:
-                    LOGGER.info('[SetConfig] resource = {:s}'.format(str(resource)))
-                    chk_type(str_resource_name, resource, (list, tuple))
-                    chk_length(str_resource_name, resource, min_length=2, max_length=2)
-                    resource_key,resource_value = resource
-                    chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
-                    str_config_message = compose_config(resource_key, resource_value)
-                    
-                    with manager.connect(host=address, port=830, username='admin', password='admin',
-                                    hostkey_verify=False, device_params={'name':'huaweiyang'},
-                                    look_for_keys=False, allow_agent=False) as m:
-                        assert(":candidate" in m.server_capabilities)
-                        with m.locked(target='candidate'):
-                            m.edit_config(config=str_config_message, default_operation="merge", target="candidate")
-                            m.commit()
-                            results.append(True)
-                    """
-                    if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
-                    LOGGER.info('[SetConfig] str_config_message[{:d}] = {:s}'.format(
-                        len(str_config_message), str(str_config_message)))
-                    self.__netconf_handler.edit_config(str_config_message, target='running')
-                    results.append(True)
-                    """
-                except Exception as e: # pylint: disable=broad-except
-                    LOGGER.exception('Exception setting {:s}: {:s}'.format(str_resource_name, str(resource)))
-                    results.append(e) # if validation fails, store the exception         
+            if self.__netconf_handler.use_candidate:
+                with self.__netconf_handler.locked(target='candidate'):
+                    results = edit_config(self.__netconf_handler, resources, target='candidate')
+                    try:
+                        self.__netconf_handler.commit()
+                    except Exception as e: # pylint: disable=broad-except
+                        LOGGER.exception('[SetConfig] Exception commiting resources: {:s}'.format(str(resources)))
+                        results = [e for _ in resources] # if commit fails, set exception in each resource
+            else:
+                results = edit_config(self.__netconf_handler, resources)
         return results
 
     def DeleteConfig(self, resources : List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
         chk_type('resources', resources, list)
         if len(resources) == 0: return []
-        results = []
-        LOGGER.info('[DeleteConfig] resources = {:s}'.format(str(resources)))
         with self.__lock:
-            for i,resource in enumerate(resources):
-                str_resource_name = 'resources[#{:d}]'.format(i)
-                try:
-                    LOGGER.info('[DeleteConfig] resource = {:s}'.format(str(resource)))
-                    chk_type(str_resource_name, resource, (list, tuple))
-                    chk_length(str_resource_name, resource, min_length=2, max_length=2)
-                    resource_key,resource_value = resource
-                    chk_string(str_resource_name + '.key', resource_key, allow_empty=False)
-                    str_config_message = compose_config(resource_key, resource_value, delete=True)
-                    
-                    with manager.connect(host=address, port=830, username='admin', password='admin',
-                                    hostkey_verify=False, device_params={'name':'huaweiyang'},
-                                    look_for_keys=False, allow_agent=False) as m:
-                        assert(":candidate" in m.server_capabilities)
-                        with m.locked(target='candidate'):
-                            m.edit_config(config=str_config_message, default_operation="merge", target="candidate")
-                            m.commit()
-                            results.append(True)
-                    
-                    """
-                    if str_config_message is None: raise UnsupportedResourceKeyException(resource_key)
-                    LOGGER.info('[DeleteConfig] str_config_message[{:d}] = {:s}'.format(
-                        len(str_config_message), str(str_config_message)))
-                    self.__netconf_handler.edit_config(str_config_message, target='running')
-                    results.append(True)
-                    """
-                except Exception as e: # pylint: disable=broad-except
-                    LOGGER.exception('Exception deleting {:s}: {:s}'.format(str_resource_name, str(resource_key)))
-                    results.append(e) # if validation fails, store the exception
+            if self.__netconf_handler.use_candidate:
+                with self.__netconf_handler.locked(target='candidate'):
+                    results = edit_config(
+                        self.__netconf_handler, resources, target='candidate', delete=True, default_operation='delete')
+                    try:
+                        self.__netconf_handler.commit()
+                    except Exception as e: # pylint: disable=broad-except
+                        LOGGER.exception('[DeleteConfig] Exception commiting resources: {:s}'.format(str(resources)))
+                        results = [e for _ in resources] # if commit fails, set exception in each resource
+            else:
+                results = edit_config(self.__netconf_handler, resources, delete=True, default_operation='delete')
         return results
 
     def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
diff --git a/src/device/service/drivers/openconfig/templates/Acl.py b/src/device/service/drivers/openconfig/templates/Acl.py
index ab07fe6fd..6cd90f373 100644
--- a/src/device/service/drivers/openconfig/templates/Acl.py
+++ b/src/device/service/drivers/openconfig/templates/Acl.py
@@ -15,7 +15,7 @@
 import logging, lxml.etree as ET
 from typing import Any, Dict, List, Tuple
 from .Namespace import NAMESPACES
-from .Tools import add_value_from_collection, add_value_from_tag
+from .Tools import add_value_from_tag
 
 LOGGER = logging.getLogger(__name__)
 
@@ -25,16 +25,16 @@ XPATH_A_IPv4      = ".//ocacl:ipv4/ocacl:config"
 XPATH_A_TRANSPORT = ".//ocacl:transport/ocacl:config"
 XPATH_A_ACTIONS   = ".//ocacl:actions/ocacl:config"
 
-XPATH_INTERFACE         = "//ocacl:acl/ocacl:interfaces/ocacl:interface"
-XPATH_I_INGRESS         = ".//ocacl:ingress-acl-sets/ocacl:ingress-acl-set"
-XPATH_I_EGRESS          = ".//ocacl:egress-acl-sets/ocacl:egress-acl-set"
+XPATH_INTERFACE   = "//ocacl:acl/ocacl:interfaces/ocacl:interface"
+XPATH_I_INGRESS   = ".//ocacl:ingress-acl-sets/ocacl:ingress-acl-set"
+XPATH_I_EGRESS    = ".//ocacl:egress-acl-sets/ocacl:egress-acl-set"
 
 def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
     #LOGGER.info('[ACL] xml_data = {:s}'.format(str(ET.tostring(xml_data))))
 
     response = []
     acl = {}
-    
+
     for xml_acl in xml_data.xpath(XPATH_ACL_SET, namespaces=NAMESPACES):
         #LOGGER.info('xml_acl = {:s}'.format(str(ET.tostring(xml_acl))))
 
@@ -49,7 +49,7 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
 
             acl_id = xml_acl_entries.find('ocacl:sequence_id', namespaces=NAMESPACES)
             add_value_from_tag(acl, 'sequence_id', acl_id)
-            
+
             for xml_ipv4 in xml_acl_entries.xpath(XPATH_A_IPv4, namespaces=NAMESPACES):
 
                 ipv4_source = xml_ipv4.find('ocacl:source_address', namespaces=NAMESPACES)
@@ -60,13 +60,13 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
 
                 ipv4_protocol = xml_ipv4.find('ocacl:protocol', namespaces=NAMESPACES)
                 add_value_from_tag(acl, 'protocol' , ipv4_protocol)
-                
+
                 ipv4_dscp = xml_ipv4.find('ocacl:dscp', namespaces=NAMESPACES)
                 add_value_from_tag(acl, 'dscp' , ipv4_dscp)
-                
+
                 ipv4_hop_limit = xml_ipv4.find('ocacl:hop_limit', namespaces=NAMESPACES)
                 add_value_from_tag(acl, 'hop_limit' , ipv4_hop_limit)
-                
+
             for xml_transport in xml_acl_entries.xpath(XPATH_A_TRANSPORT, namespaces=NAMESPACES):
 
                 transport_source = xml_transport.find('ocacl:source_port', namespaces=NAMESPACES)
@@ -74,22 +74,22 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
 
                 transport_destination = xml_transport.find('ocacl:destination_port', namespaces=NAMESPACES)
                 add_value_from_tag(acl, 'destination_port' ,transport_destination)
-                
+
                 transport_tcp_flags = xml_transport.find('ocacl:tcp_flags', namespaces=NAMESPACES)
                 add_value_from_tag(acl, 'tcp_flags' ,transport_tcp_flags)
-            
+
             for xml_action in xml_acl_entries.xpath(XPATH_A_ACTIONS, namespaces=NAMESPACES):
 
                 action = xml_action.find('ocacl:forwarding_action', namespaces=NAMESPACES)
                 add_value_from_tag(acl, 'forwarding_action' ,action)
-                
+
                 log_action = xml_action.find('ocacl:log_action', namespaces=NAMESPACES)
                 add_value_from_tag(acl, 'log_action' ,log_action)
 
             resource_key =  '/acl/acl-set[{:s}][{:s}]/acl-entry[{:s}]'.format(
                 acl['name'], acl['type'], acl['sequence-id'])
             response.append((resource_key,acl))
-    
+
     for xml_interface in xml_data.xpath(XPATH_INTERFACE, namespaces=NAMESPACES):
 
         interface = {}
@@ -104,7 +104,7 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
 
             i_type = xml_ingress.find('ocacl:type_ingress', namespaces=NAMESPACES)
             add_value_from_tag(interface, 'ingress_type' , i_type)
-            
+
             resource_key =  '/acl/interfaces/ingress[{:s}][{:s}]'.format(
                 acl['name'], acl['type'])
             response.append((resource_key,interface))
@@ -116,7 +116,7 @@ def parse(xml_data : ET.Element) -> List[Tuple[str, Dict[str, Any]]]:
 
             e_type = xml_egress.find('ocacl:type_egress', namespaces=NAMESPACES)
             add_value_from_tag(interface, 'egress_type' , e_type)
-    
+
             resource_key =  '/acl/interfaces/egress[{:s}][{:s}]'.format(
                 acl['name'], acl['type'])
             response.append((resource_key,interface))
diff --git a/src/device/service/drivers/openconfig/templates/Namespace.py b/src/device/service/drivers/openconfig/templates/Namespace.py
index d9bdae323..94af95566 100644
--- a/src/device/service/drivers/openconfig/templates/Namespace.py
+++ b/src/device/service/drivers/openconfig/templates/Namespace.py
@@ -13,8 +13,9 @@
 # limitations under the License.
 
 
-NAMESPACE_NETCONF       = 'urn:ietf:params:xml:ns:netconf:base:1.0'
+NAMESPACE_NETCONF                = 'urn:ietf:params:xml:ns:netconf:base:1.0'
 
+NAMESPACE_ACL                    = 'http://openconfig.net/yang/acl'
 NAMESPACE_BGP_POLICY             = 'http://openconfig.net/yang/bgp-policy'
 NAMESPACE_INTERFACES             = 'http://openconfig.net/yang/interfaces'
 NAMESPACE_INTERFACES_IP          = 'http://openconfig.net/yang/interfaces/ip'
@@ -28,8 +29,6 @@ NAMESPACE_POLICY_TYPES_2         = 'http://openconfig.net/yang/policy_types'
 NAMESPACE_ROUTING_POLICY         = 'http://openconfig.net/yang/routing-policy'
 NAMESPACE_VLAN                   = 'http://openconfig.net/yang/vlan'
 
-NAMESPACE_ACL                    = 'http://openconfig.net/yang/acl'
-
 NAMESPACES = {
     'nc'   : NAMESPACE_NETCONF,
     'ocacl': NAMESPACE_ACL,
diff --git a/src/device/service/drivers/openconfig/templates/RoutingPolicy.py b/src/device/service/drivers/openconfig/templates/RoutingPolicy.py
index aae848370..369732de3 100644
--- a/src/device/service/drivers/openconfig/templates/RoutingPolicy.py
+++ b/src/device/service/drivers/openconfig/templates/RoutingPolicy.py
@@ -15,7 +15,7 @@
 import copy, logging, lxml.etree as ET
 from typing import Any, Dict, List, Tuple
 from .Namespace import NAMESPACES
-from .Tools import add_value_from_collection, add_value_from_tag
+from .Tools import add_value_from_tag
 
 LOGGER = logging.getLogger(__name__)
 
-- 
GitLab


From ff543f5405094a06a68d3d076b069b5e69277738 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Tue, 17 May 2022 15:27:51 +0200
Subject: [PATCH 08/60] Device component: - Updated default OpenConfig unitary
 test template config - Added minor code improvements in OpenConfig Driver

---
 .../service/drivers/openconfig/OpenConfigDriver.py  | 13 +++++++------
 src/device/tests/Device_OpenConfig_Template.py      | 13 +++++++++----
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index 741142363..74b30e013 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -63,9 +63,9 @@ class NetconfSessionHandler:
         self.__username       = settings.get('username')
         self.__password       = settings.get('password')
         self.__key_filename   = settings.get('key_filename')
-        self.__hostkey_verify = settings.get('hostkey_verify')
-        self.__look_for_keys  = settings.get('look_for_keys')
-        self.__allow_agent    = settings.get('allow_agent')
+        self.__hostkey_verify = settings.get('hostkey_verify', True)
+        self.__look_for_keys  = settings.get('look_for_keys', True)
+        self.__allow_agent    = settings.get('allow_agent', True)
         self.__force_running  = settings.get('force_running', False)
         self.__device_params  = settings.get('device_params')
         self.__manager_params = settings.get('manager_params')
@@ -183,8 +183,9 @@ def do_sampling(samples_cache : SamplesCache, resource_key : str, out_samples :
 
 def edit_config(
     netconf_handler : NetconfSessionHandler, resources : List[Tuple[str, Any]], delete=False, target='running',
-    default_operation='merge', test_option=None, error_option=None, format='xml' # pylint: disable=redefined-builtin
+    default_operation=None, test_option=None, error_option=None, format='xml' # pylint: disable=redefined-builtin
 ):
+    if default_operation is None: default_operation = 'delete' if delete else 'merge'
     str_method = 'DeleteConfig' if delete else 'SetConfig'
     LOGGER.info('[{:s}] resources = {:s}'.format(str_method, str(resources)))
     results = [None for _ in resources]
@@ -296,14 +297,14 @@ class OpenConfigDriver(_Driver):
             if self.__netconf_handler.use_candidate:
                 with self.__netconf_handler.locked(target='candidate'):
                     results = edit_config(
-                        self.__netconf_handler, resources, target='candidate', delete=True, default_operation='delete')
+                        self.__netconf_handler, resources, target='candidate', delete=True)
                     try:
                         self.__netconf_handler.commit()
                     except Exception as e: # pylint: disable=broad-except
                         LOGGER.exception('[DeleteConfig] Exception commiting resources: {:s}'.format(str(resources)))
                         results = [e for _ in resources] # if commit fails, set exception in each resource
             else:
-                results = edit_config(self.__netconf_handler, resources, delete=True, default_operation='delete')
+                results = edit_config(self.__netconf_handler, resources, delete=True)
         return results
 
     def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
diff --git a/src/device/tests/Device_OpenConfig_Template.py b/src/device/tests/Device_OpenConfig_Template.py
index df588b3d8..d95e86dfa 100644
--- a/src/device/tests/Device_OpenConfig_Template.py
+++ b/src/device/tests/Device_OpenConfig_Template.py
@@ -20,15 +20,20 @@ DEVICE_OC_ADDRESS  = '127.0.0.1'  # populate the Netconf Server IP address of th
 DEVICE_OC_PORT     = 830          # populate the Netconf Server port of the device to test
 DEVICE_OC_USERNAME = 'username'   # populate the Netconf Server username of the device to test
 DEVICE_OC_PASSWORD = 'password'   # populate the Netconf Server password of the device to test
-DEVICE_OC_TIMEOUT  = 120
+DEVICE_OC_TIMEOUT  = 15
 
 DEVICE_OC_ID = json_device_id(DEVICE_OC_UUID)
 DEVICE_OC    = json_device_packetrouter_disabled(DEVICE_OC_UUID)
 
 DEVICE_OC_CONNECT_RULES = json_device_connect_rules(DEVICE_OC_ADDRESS, DEVICE_OC_PORT, {
-    'username': DEVICE_OC_USERNAME,
-    'password': DEVICE_OC_PASSWORD,
-    'timeout' : DEVICE_OC_TIMEOUT,
+    'username'       : DEVICE_OC_USERNAME,
+    'password'       : DEVICE_OC_PASSWORD,
+    'force_running'  : True,
+    'hostkey_verify' : True,
+    'look_for_keys'  : True,
+    'allow_agent'    : True,
+    'device_params'  : {'name': 'default'},
+    'manager_params' : {'timeout' : DEVICE_OC_TIMEOUT},
 })
 
 DEVICE_OC_CONFIG_RULES   = []           # populate your configuration rules to test
-- 
GitLab


From 1429d8b658671c70709e29707b257cca15ee487d Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Tue, 17 May 2022 15:35:24 +0200
Subject: [PATCH 09/60] Device component: - OpenConfigDriver: code cleanup and
 added default values

---
 .../service/drivers/openconfig/OpenConfigDriver.py       | 9 ++++-----
 1 file changed, 4 insertions(+), 5 deletions(-)

diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index 74b30e013..29e8e13a6 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -67,9 +67,9 @@ class NetconfSessionHandler:
         self.__look_for_keys  = settings.get('look_for_keys', True)
         self.__allow_agent    = settings.get('allow_agent', True)
         self.__force_running  = settings.get('force_running', False)
-        self.__device_params  = settings.get('device_params')
-        self.__manager_params = settings.get('manager_params')
-        self.__nc_params      = settings.get('nc_params')
+        self.__device_params  = settings.get('device_params', {})
+        self.__manager_params = settings.get('manager_params', {})
+        self.__nc_params      = settings.get('nc_params', {})
         self.__manager : Manager   = None
         self.__candidate_supported = False
 
@@ -296,8 +296,7 @@ class OpenConfigDriver(_Driver):
         with self.__lock:
             if self.__netconf_handler.use_candidate:
                 with self.__netconf_handler.locked(target='candidate'):
-                    results = edit_config(
-                        self.__netconf_handler, resources, target='candidate', delete=True)
+                    results = edit_config(self.__netconf_handler, resources, target='candidate', delete=True)
                     try:
                         self.__netconf_handler.commit()
                     except Exception as e: # pylint: disable=broad-except
-- 
GitLab


From a3e455ec3e3d3c9939fe88805e2c0e33a2c21f2f Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Tue, 17 May 2022 15:45:07 +0200
Subject: [PATCH 10/60] Device component: - solved minor bug with default
 openconfig operations.

---
 src/device/service/drivers/openconfig/OpenConfigDriver.py | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index 29e8e13a6..edc5130e0 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -183,9 +183,8 @@ def do_sampling(samples_cache : SamplesCache, resource_key : str, out_samples :
 
 def edit_config(
     netconf_handler : NetconfSessionHandler, resources : List[Tuple[str, Any]], delete=False, target='running',
-    default_operation=None, test_option=None, error_option=None, format='xml' # pylint: disable=redefined-builtin
+    default_operation='merge', test_option=None, error_option=None, format='xml' # pylint: disable=redefined-builtin
 ):
-    if default_operation is None: default_operation = 'delete' if delete else 'merge'
     str_method = 'DeleteConfig' if delete else 'SetConfig'
     LOGGER.info('[{:s}] resources = {:s}'.format(str_method, str(resources)))
     results = [None for _ in resources]
-- 
GitLab


From d36a6c29ad4c8d00676e839278fc2abc9f143bb3 Mon Sep 17 00:00:00 2001
From: PabloArmingolRobles <pablo.armingolrobles.practicas@telefonica.com>
Date: Tue, 17 May 2022 16:02:49 +0200
Subject: [PATCH 11/60] Device debug log reduced

---
 src/device/service/drivers/openconfig/OpenConfigDriver.py | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index edc5130e0..4965ced4e 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -31,7 +31,7 @@ from .templates import ALL_RESOURCE_KEYS, EMPTY_CONFIG, compose_config, get_filt
 from .RetryDecorator import retry
 
 
-DEBUG_MODE = True
+DEBUG_MODE = False
 logging.getLogger('ncclient.manager').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
 logging.getLogger('ncclient.transport.ssh').setLevel(logging.DEBUG if DEBUG_MODE else logging.WARNING)
 logging.getLogger('apscheduler.executors.default').setLevel(logging.INFO if DEBUG_MODE else logging.ERROR)
-- 
GitLab


From bc601571b92b188de8565fadf7b2721d4201afb2 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Tue, 17 May 2022 16:14:54 +0200
Subject: [PATCH 12/60] Device component: - Corrected default values in unitary
 test config template - Minor code styling

---
 src/device/service/drivers/openconfig/OpenConfigDriver.py   | 1 -
 src/device/service/drivers/openconfig/templates/__init__.py | 2 +-
 src/device/tests/Device_OpenConfig_Template.py              | 2 +-
 3 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/device/service/drivers/openconfig/OpenConfigDriver.py b/src/device/service/drivers/openconfig/OpenConfigDriver.py
index 4965ced4e..b28217898 100644
--- a/src/device/service/drivers/openconfig/OpenConfigDriver.py
+++ b/src/device/service/drivers/openconfig/OpenConfigDriver.py
@@ -395,4 +395,3 @@ class OpenConfigDriver(_Driver):
                 return
             if sample is None: continue
             yield sample
-            
\ No newline at end of file
diff --git a/src/device/service/drivers/openconfig/templates/__init__.py b/src/device/service/drivers/openconfig/templates/__init__.py
index a6825ea41..901f5cf02 100644
--- a/src/device/service/drivers/openconfig/templates/__init__.py
+++ b/src/device/service/drivers/openconfig/templates/__init__.py
@@ -16,7 +16,7 @@ import json, logging, lxml.etree as ET, re
 from typing import Any, Dict
 from jinja2 import Environment, PackageLoader, select_autoescape
 from device.service.driver_api._Driver import (
-    RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES, RESOURCE_ROUTING_POLICIES,RESOURCE_ACL)
+    RESOURCE_ENDPOINTS, RESOURCE_INTERFACES, RESOURCE_NETWORK_INSTANCES, RESOURCE_ROUTING_POLICIES, RESOURCE_ACL)
 from .EndPoints import parse as parse_endpoints
 from .Interfaces import parse as parse_interfaces, parse_counters
 from .NetworkInstances import parse as parse_network_instances
diff --git a/src/device/tests/Device_OpenConfig_Template.py b/src/device/tests/Device_OpenConfig_Template.py
index d95e86dfa..6afa2721f 100644
--- a/src/device/tests/Device_OpenConfig_Template.py
+++ b/src/device/tests/Device_OpenConfig_Template.py
@@ -28,7 +28,7 @@ DEVICE_OC    = json_device_packetrouter_disabled(DEVICE_OC_UUID)
 DEVICE_OC_CONNECT_RULES = json_device_connect_rules(DEVICE_OC_ADDRESS, DEVICE_OC_PORT, {
     'username'       : DEVICE_OC_USERNAME,
     'password'       : DEVICE_OC_PASSWORD,
-    'force_running'  : True,
+    'force_running'  : False,
     'hostkey_verify' : True,
     'look_for_keys'  : True,
     'allow_agent'    : True,
-- 
GitLab


From 1e59ae679ab248d06eae03ac06615cbe58854e59 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Tue, 17 May 2022 17:02:03 +0200
Subject: [PATCH 13/60] Device component, MicroWaveDriver: - code styling and
 cleanup

---
 src/common/tools/object_factory/Device.py     |   3 +-
 .../drivers/microwave/IETFApiDriver.py        |   8 +-
 src/device/service/drivers/microwave/Tools.py | 138 +++++++-----------
 src/device/tests/Device_Microwave_Template.py |  22 +--
 4 files changed, 72 insertions(+), 99 deletions(-)

diff --git a/src/common/tools/object_factory/Device.py b/src/common/tools/object_factory/Device.py
index c4ef8173c..d5990db5e 100644
--- a/src/common/tools/object_factory/Device.py
+++ b/src/common/tools/object_factory/Device.py
@@ -90,7 +90,8 @@ def json_device_microwave_disabled(
         drivers : List[Dict] = DEVICE_MICROWAVE_DRIVERS
     ):
     return json_device(
-        device_uuid, DEVICE_MICROWAVE_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules, drivers=drivers)
+        device_uuid, DEVICE_MICROWAVE_TYPE, DEVICE_DISABLED, endpoints=endpoints, config_rules=config_rules,
+        drivers=drivers)
 
 def json_device_p4_disabled(
         device_uuid : str, endpoints : List[Dict] = [], config_rules : List[Dict] = [],
diff --git a/src/device/service/drivers/microwave/IETFApiDriver.py b/src/device/service/drivers/microwave/IETFApiDriver.py
index 0f68445f2..4d5ec439f 100644
--- a/src/device/service/drivers/microwave/IETFApiDriver.py
+++ b/src/device/service/drivers/microwave/IETFApiDriver.py
@@ -65,7 +65,6 @@ class IETFApiDriver(_Driver):
                 results.extend(config_getter(self.__ietf_root, resource_key, self.__timeout))
         return results
 
-
     def SetConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
         results = []
         if len(resources) == 0:
@@ -86,7 +85,6 @@ class IETFApiDriver(_Driver):
                 results.extend(data)
         return results
 
-
     def DeleteConfig(self, resources: List[Tuple[str, Any]]) -> List[Union[bool, Exception]]:
         results = []
         if len(resources) == 0: return results
@@ -98,15 +96,15 @@ class IETFApiDriver(_Driver):
         return results
 
     def SubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
-        # TODO: TAPI does not support monitoring by now
+        # TODO: IETF API Driver does not support monitoring by now
         return [False for _ in subscriptions]
 
     def UnsubscribeState(self, subscriptions : List[Tuple[str, float, float]]) -> List[Union[bool, Exception]]:
-        # TODO: TAPI does not support monitoring by now
+        # TODO: IETF API Driver does not support monitoring by now
         return [False for _ in subscriptions]
 
     def GetState(
         self, blocking=False, terminate : Optional[threading.Event] = None
     ) -> Iterator[Tuple[float, str, Any]]:
-        # TODO: TAPI does not support monitoring by now
+        # TODO: IETF API Driver does not support monitoring by now
         return []
diff --git a/src/device/service/drivers/microwave/Tools.py b/src/device/service/drivers/microwave/Tools.py
index 6398b6867..93498f72d 100644
--- a/src/device/service/drivers/microwave/Tools.py
+++ b/src/device/service/drivers/microwave/Tools.py
@@ -22,21 +22,28 @@ def find_key(resource, key):
     return json.loads(resource[1])[key]
 
 # this function exports only the endpoints which are not already involved in a microwave physical link
-def isAnExportableEndpoint(node, termination_point_id, links):
+def is_exportable_endpoint(node, termination_point_id, links):
     # for each link we check if the endpoint (termination_point_id) is already used by an existing link
     for link in links:
         src = link['source']
         dest = link['destination']
         if dest['dest-node'] == node and dest['dest-tp'] == termination_point_id:
             return False
-        elif src['source-node'] == node and src['source-tp'] == termination_point_id:
+        if src['source-node'] == node and src['source-tp'] == termination_point_id:
             return False
-
     return True
 
 def config_getter(root_url, resource_key, timeout):
     # getting endpoints
-    url = '{:s}/nmswebs/restconf/data/ietf-network:networks/network=SIAE-ETH-TOPOLOGY?fields=ietf-network-topology:link(link-id;destination(dest-node;dest-tp);source(source-node;source-tp));node(node-id;ietf-network-topology:termination-point(tp-id;ietf-te-topology:te/name)))'.format(root_url)
+    network_name = 'SIAE-ETH-TOPOLOGY'
+    FIELDS = ''.join([
+        'ietf-network-topology:',
+        'link(link-id;destination(dest-node;dest-tp);source(source-node;source-tp));',
+        'node(node-id;ietf-network-topology:termination-point(tp-id;ietf-te-topology:te/name)))',
+    ])
+    URL_TEMPLATE = '{:s}/nmswebs/restconf/data/ietf-network:networks/network={:s}?fields={:s}'
+    url = URL_TEMPLATE.format(root_url, network_name, FIELDS)
+
     result = []
     try:
         response = requests.get(url, timeout=timeout, verify=False)
@@ -47,23 +54,20 @@ def config_getter(root_url, resource_key, timeout):
         result.append((resource_key, e))
     else:
         context = json.loads(response.content)
-    
-
         if resource_key == RESOURCE_ENDPOINTS:
-            if not (context.get('ietf-network:network') is None):
-                network_instance = context['ietf-network:network']
-                if not (network_instance.get('ietf-network-topology:link') is None):
-                    links = network_instance['ietf-network-topology:link']  
-
-                    for sip in network_instance['node']:
-                        tp = sip['ietf-network-topology:termination-point']
-                        node_id = sip['node-id']
-                        for te in tp:
-                            tp_id = te['tp-id']
-                            if isAnExportableEndpoint(node_id, tp_id, links):
-                                result.append(('/endpoints/endpoint[{:s}:{:s}]'.format(node_id,tp_id), {'uuid': tp_id, 'type': te['ietf-te-topology:te']['name']}))
-
-    # getting created services 
+            network_instance = context.get('ietf-network:network', {})
+            links = network_instance.get('ietf-network-topology:link', [])
+            for sip in network_instance['node']:
+                tp = sip['ietf-network-topology:termination-point']
+                node_id = sip['node-id']
+                for te in tp:
+                    tp_id = te['tp-id']
+                    if not is_exportable_endpoint(node_id, tp_id, links): continue
+                    resource_key = '/endpoints/endpoint[{:s}:{:s}]'.format(node_id,tp_id)
+                    resource_value = {'uuid': tp_id, 'type': te['ietf-te-topology:te']['name']}
+                    result.append((resource_key, resource_value))
+
+    # getting created services
     url = '{:s}/nmswebs/restconf/data/ietf-eth-tran-service:etht-svc'.format(root_url)
     try:
         response = requests.get(url, timeout=timeout, verify=False)
@@ -74,76 +78,47 @@ def config_getter(root_url, resource_key, timeout):
         result.append((resource_key, e))
     else:
         context = json.loads(response.content)
-    
-
         if resource_key == RESOURCE_ENDPOINTS:
-            if not (context.get('ietf-eth-tran-service:etht-svc') is None):
-                etht_service = context['ietf-eth-tran-service:etht-svc']
-                if not (etht_service.get('etht-svc-instances') is None):
-                    service_instances = etht_service['etht-svc-instances'] 
-            
-                    for service in service_instances:
-                        service_name = service['etht-svc-name']
-                        result.append(('/services/service[{:s}]'.format(service_name), {'uuid': service_name, 'type': service['etht-svc-type']}))
-            
+            etht_service = context.get('ietf-eth-tran-service:etht-svc', {})
+            service_instances = etht_service.get('etht-svc-instances', [])
+            for service in service_instances:
+                service_name = service['etht-svc-name']
+                resource_key = '/services/service[{:s}]'.format(service_name)
+                resource_value = {'uuid': service_name, 'type': service['etht-svc-type']}
+                result.append((resource_key, resource_value))
     return result
 
-
 def create_connectivity_service(
     root_url, timeout, uuid, node_id_src, tp_id_src, node_id_dst, tp_id_dst, vlan_id):
 
     url = '{:s}/nmswebs/restconf/data/ietf-eth-tran-service:etht-svc'.format(root_url)
     headers = {'content-type': 'application/json'}
-    data = {}
-    
     data = {
-            "etht-svc-instances": 
-            [
-	            {
-		            "etht-svc-name": uuid,
-		            "etht-svc-type": "ietf-eth-tran-types:p2p-svc",
-		            "etht-svc-end-points": 
-                    [
-		                {
-			                "etht-svc-access-points": 
-                            [
-			                    {       
-			                        "access-node-id": node_id_src,
-			                        "access-ltp-id": tp_id_src,
-			                        "access-point-id": "1"
-			                    }
-			                ],
-		                    "outer-tag": 
-                                {
-			                        "vlan-value": vlan_id,
-			                        "tag-type": "ietf-eth-tran-types:classify-c-vlan"
-		                        },
-		                    "etht-svc-end-point-name": node_id_src+':'+str(tp_id_src),
-		                    "service-classification-type": "ietf-eth-tran-types:vlan-classification"
-		                },
-		                {
-		                    "etht-svc-access-points": 
-                            [
-		                        {
-			                        "access-node-id": node_id_dst,
-			                        "access-ltp-id": tp_id_dst,
-			                        "access-point-id": "2"
-		                        }
-		                    ],
-		                    "outer-tag": 
-                                {
-			                        "vlan-value": vlan_id,
-			                        "tag-type": "ietf-eth-tran-types:classify-c-vlan"
-		                        },
-		                    "etht-svc-end-point-name": node_id_dst+':'+str(tp_id_dst),
-		                    "service-classification-type": "ietf-eth-tran-types:vlan-classification"
-		                }
-		            ]	
-	            }
-	        ]       
-           }
-
-    
+        'etht-svc-instances': [
+            {
+                'etht-svc-name': uuid,
+                'etht-svc-type': 'ietf-eth-tran-types:p2p-svc',
+                'etht-svc-end-points': [
+                    {
+                        'etht-svc-access-points': [
+                            {'access-node-id': node_id_src, 'access-ltp-id': tp_id_src, 'access-point-id': '1'}
+                        ],
+                        'outer-tag': {'vlan-value': vlan_id, 'tag-type': 'ietf-eth-tran-types:classify-c-vlan'},
+                        'etht-svc-end-point-name': '{:s}:{:s}'.format(str(node_id_src), str(tp_id_src)),
+                        'service-classification-type': 'ietf-eth-tran-types:vlan-classification'
+                    },
+                    {
+                        'etht-svc-access-points': [
+                            {'access-node-id': node_id_dst, 'access-ltp-id': tp_id_dst, 'access-point-id': '2'}
+                        ],
+                        'outer-tag': {'vlan-value': vlan_id, 'tag-type': 'ietf-eth-tran-types:classify-c-vlan'},
+                        'etht-svc-end-point-name': '{:s}:{:s}'.format(str(node_id_dst), str(tp_id_dst)),
+                        'service-classification-type': 'ietf-eth-tran-types:vlan-classification'
+                    }
+                ]
+            }
+        ]
+    }
     results = []
     try:
         LOGGER.info('Connectivity service {:s}: {:s}'.format(str(uuid), str(data)))
@@ -159,7 +134,6 @@ def create_connectivity_service(
         results.append(response.status_code == 201)
     return results
 
-
 def delete_connectivity_service(root_url, timeout, uuid):
     url = '{:s}/nmswebs/restconf/data/ietf-eth-tran-service:etht-svc/etht-svc-instances={:s}'
     url = url.format(root_url, uuid)
diff --git a/src/device/tests/Device_Microwave_Template.py b/src/device/tests/Device_Microwave_Template.py
index 1f2d57a1d..710d28bec 100644
--- a/src/device/tests/Device_Microwave_Template.py
+++ b/src/device/tests/Device_Microwave_Template.py
@@ -16,10 +16,10 @@ from common.tools.object_factory.ConfigRule import json_config_rule_delete, json
 from common.tools.object_factory.Device import (
     json_device_connect_rules, json_device_id, json_device_microwave_disabled)
 
-DEVICE_MICROWAVE_UUID    = 'DEVICE-MICROWAVE'     # populate 'device-uuid' of the MICROWAVE SMDC server
-DEVICE_MICROWAVE_ADDRESS = '127.0.0.1'       # populate 'address' of the MICROWAVE SMDC server
-DEVICE_MICROWAVE_PORT    = 8443                   # populate 'port' of the MICROWAVE SMDC server
-DEVICE_MICROWAVE_TIMEOUT = 120                    # populate 'timeout' of the MICROWAVE SMDC server
+DEVICE_MICROWAVE_UUID    = 'DEVICE-MICROWAVE'   # populate 'device-uuid' of the MICROWAVE SMDC server
+DEVICE_MICROWAVE_ADDRESS = '127.0.0.1'          # populate 'address' of the MICROWAVE SMDC server
+DEVICE_MICROWAVE_PORT    = 8443                 # populate 'port' of the MICROWAVE SMDC server
+DEVICE_MICROWAVE_TIMEOUT = 120                  # populate 'timeout' of the MICROWAVE SMDC server
 
 DEVICE_MICROWAVE_ID = json_device_id(DEVICE_MICROWAVE_UUID)
 DEVICE_MICROWAVE    = json_device_microwave_disabled(DEVICE_MICROWAVE_UUID)
@@ -30,17 +30,17 @@ DEVICE_MICROWAVE_CONNECT_RULES = json_device_connect_rules(DEVICE_MICROWAVE_ADDR
 
 DEVICE_MICROWAVE_CONFIG_RULES = [
     json_config_rule_set('/services/service[service_uuid]', {
-        'uuid'                      : 'service-uuid',       # populate 'service_name of the service to test
-        'node_id_src'               : '172.26.60.243',      # populate 'node_id_src' of the service to test
-        'tp_id_src'                 : 9,                    # populate 'tp_id_src' of the service to test
-        'node_id_dst'               : '172.26.60.244',      # populate 'node_id_dst' of the service to test
-        'tp_id_dst'                 : 9,                    # populate 'tp_id_dst' of the service to test
-        'vlan_id'                   : 121,                  # populate 'vlan_id' of the service to test
+        'uuid'       : 'service-uuid',      # populate 'service_name of the service to test
+        'node_id_src': '172.26.60.243',     # populate 'node_id_src' of the service to test
+        'tp_id_src'  : 9,                   # populate 'tp_id_src' of the service to test
+        'node_id_dst': '172.26.60.244',     # populate 'node_id_dst' of the service to test
+        'tp_id_dst'  : 9,                   # populate 'tp_id_dst' of the service to test
+        'vlan_id'    : 121,                 # populate 'vlan_id' of the service to test
     })
 ]
 
 DEVICE_MICROWAVE_DECONFIG_RULES = [
     json_config_rule_delete('/services/service[service-uuid]', {
-        'uuid': 'service-uuid'                              # populate 'service_name' of the service to test
+        'uuid': 'service-uuid'              # populate 'service_name' of the service to test
     })
 ]
-- 
GitLab


From 6bad547580fa1db0e4b0d2b8a4a045cc1279ad32 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Tue, 17 May 2022 17:20:55 +0200
Subject: [PATCH 14/60] Device component: remove wrongly placed requirement.

---
 src/device/requirements.in | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/device/requirements.in b/src/device/requirements.in
index eda69047b..3bac91e71 100644
--- a/src/device/requirements.in
+++ b/src/device/requirements.in
@@ -3,7 +3,6 @@ APScheduler==3.8.1
 fastcache==1.1.0
 grpcio==1.43.0
 grpcio-health-checking==1.43.0
-grpcio-tools==1.43.0
 Jinja2==3.0.3
 ncclient==0.6.13
 p4runtime==1.3.0
-- 
GitLab


From 30f28f8b15c2e0c014aae1ce9e9e86682a6075c3 Mon Sep 17 00:00:00 2001
From: Sergio <sergio.gonzalez.diaz@atos.net>
Date: Tue, 17 May 2022 18:53:01 +0200
Subject: [PATCH 15/60] Remove cobertura reports

---
 src/monitoring/.gitlab-ci.yml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/monitoring/.gitlab-ci.yml b/src/monitoring/.gitlab-ci.yml
index f71541776..2496d0288 100644
--- a/src/monitoring/.gitlab-ci.yml
+++ b/src/monitoring/.gitlab-ci.yml
@@ -58,7 +58,7 @@ unit test monitoring:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -79,7 +79,7 @@ unit test monitoring:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
  
 # Deployment of the service in Kubernetes Cluster
 deploy monitoring:
-- 
GitLab


From 9139a60ed3ffa76e78931a8772d1e2eda4a0f629 Mon Sep 17 00:00:00 2001
From: Sergio <sergio.gonzalez.diaz@atos.net>
Date: Tue, 17 May 2022 19:07:43 +0200
Subject: [PATCH 16/60] Remove coberutra files from .gitlab-ci.yaml

---
 src/compute/.gitlab-ci.yml                          | 4 ++--
 src/context/.gitlab-ci.yml                          | 4 ++--
 src/dbscanserving/.gitlab-ci.yml                    | 4 ++--
 src/device/.gitlab-ci.yml                           | 4 ++--
 src/interdomain/.gitlab-ci.yml                      | 6 ++++--
 src/l3_attackmitigator/.gitlab-ci.yml               | 4 ++--
 src/l3_centralizedattackdetector/.gitlab-ci.yml     | 4 ++--
 src/l3_distributedattackdetector/.gitlab-ci.yml     | 4 ++--
 src/opticalattackmitigator/.gitlab-ci.yml           | 4 ++--
 src/opticalcentralizedattackdetector/.gitlab-ci.yml | 4 ++--
 src/service/.gitlab-ci.yml                          | 4 ++--
 src/webui/.gitlab-ci.yml                            | 6 ++++--
 12 files changed, 28 insertions(+), 24 deletions(-)

diff --git a/src/compute/.gitlab-ci.yml b/src/compute/.gitlab-ci.yml
index 7daa1764a..3eb86b9d9 100644
--- a/src/compute/.gitlab-ci.yml
+++ b/src/compute/.gitlab-ci.yml
@@ -56,7 +56,7 @@ unit test compute:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -76,7 +76,7 @@ unit test compute:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy compute:
diff --git a/src/context/.gitlab-ci.yml b/src/context/.gitlab-ci.yml
index c0cbef8d7..3d053036e 100644
--- a/src/context/.gitlab-ci.yml
+++ b/src/context/.gitlab-ci.yml
@@ -58,7 +58,7 @@ unit test context:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -79,7 +79,7 @@ unit test context:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy context:
diff --git a/src/dbscanserving/.gitlab-ci.yml b/src/dbscanserving/.gitlab-ci.yml
index 1e499fae2..1f2158384 100644
--- a/src/dbscanserving/.gitlab-ci.yml
+++ b/src/dbscanserving/.gitlab-ci.yml
@@ -56,7 +56,7 @@ unit test dbscanserving:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -76,7 +76,7 @@ unit test dbscanserving:
     when: always
     reports:
       junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-      cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+      # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 
 # Deployment of the dbscanserving service in Kubernetes Cluster
diff --git a/src/device/.gitlab-ci.yml b/src/device/.gitlab-ci.yml
index aa2f9114a..d58d5f1f3 100644
--- a/src/device/.gitlab-ci.yml
+++ b/src/device/.gitlab-ci.yml
@@ -55,7 +55,7 @@ unit test device:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +75,7 @@ unit test device:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy device:
diff --git a/src/interdomain/.gitlab-ci.yml b/src/interdomain/.gitlab-ci.yml
index f4dd49fd0..f3958d07e 100644
--- a/src/interdomain/.gitlab-ci.yml
+++ b/src/interdomain/.gitlab-ci.yml
@@ -54,7 +54,9 @@ unit test service:
     - sleep 5
     - docker ps -a
     - docker logs $IMAGE_NAME
-    - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml; coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml; coverage report --include='${IMAGE_NAME}/*' --show-missing"
+    - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
     - docker rm -f $IMAGE_NAME
@@ -73,7 +75,7 @@ unit test service:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy service:
diff --git a/src/l3_attackmitigator/.gitlab-ci.yml b/src/l3_attackmitigator/.gitlab-ci.yml
index dbf8d90fc..d9f7fe5d7 100644
--- a/src/l3_attackmitigator/.gitlab-ci.yml
+++ b/src/l3_attackmitigator/.gitlab-ci.yml
@@ -55,7 +55,7 @@ unit test l3_attackmitigator:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +75,7 @@ unit test l3_attackmitigator:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy l3_attackmitigator:
diff --git a/src/l3_centralizedattackdetector/.gitlab-ci.yml b/src/l3_centralizedattackdetector/.gitlab-ci.yml
index 43ca269d3..c9c461c81 100644
--- a/src/l3_centralizedattackdetector/.gitlab-ci.yml
+++ b/src/l3_centralizedattackdetector/.gitlab-ci.yml
@@ -55,7 +55,7 @@ unit test l3_centralizedattackdetector:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +75,7 @@ unit test l3_centralizedattackdetector:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy l3_centralizedattackdetector:
diff --git a/src/l3_distributedattackdetector/.gitlab-ci.yml b/src/l3_distributedattackdetector/.gitlab-ci.yml
index 1e34c6c7e..175efe81e 100644
--- a/src/l3_distributedattackdetector/.gitlab-ci.yml
+++ b/src/l3_distributedattackdetector/.gitlab-ci.yml
@@ -55,7 +55,7 @@ unit test l3_distributedattackdetector:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +75,7 @@ unit test l3_distributedattackdetector:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy l3_distributedattackdetector:
diff --git a/src/opticalattackmitigator/.gitlab-ci.yml b/src/opticalattackmitigator/.gitlab-ci.yml
index a39a83f6f..f1d69e02f 100644
--- a/src/opticalattackmitigator/.gitlab-ci.yml
+++ b/src/opticalattackmitigator/.gitlab-ci.yml
@@ -55,7 +55,7 @@ unit test opticalattackmitigator:
     - sleep 5
     - docker ps -a
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +75,7 @@ unit test opticalattackmitigator:
     when: always
     reports:
       junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-      cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+      # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 
 # Deployment of the opticalattackmitigator service in Kubernetes Cluster
diff --git a/src/opticalcentralizedattackdetector/.gitlab-ci.yml b/src/opticalcentralizedattackdetector/.gitlab-ci.yml
index 8a1445e80..7deaf0af3 100644
--- a/src/opticalcentralizedattackdetector/.gitlab-ci.yml
+++ b/src/opticalcentralizedattackdetector/.gitlab-ci.yml
@@ -55,7 +55,7 @@ unit test opticalcentralizedattackdetector:
     - sleep 5
     - docker ps -a
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +75,7 @@ unit test opticalcentralizedattackdetector:
     when: always
     reports:
       junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-      cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+      # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 
 # Deployment of the opticalcentralizedattackdetector service in Kubernetes Cluster
diff --git a/src/service/.gitlab-ci.yml b/src/service/.gitlab-ci.yml
index 3f845a9dd..f3958d07e 100644
--- a/src/service/.gitlab-ci.yml
+++ b/src/service/.gitlab-ci.yml
@@ -55,7 +55,7 @@ unit test service:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +75,7 @@ unit test service:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy service:
diff --git a/src/webui/.gitlab-ci.yml b/src/webui/.gitlab-ci.yml
index 65fd71278..23a656b1f 100644
--- a/src/webui/.gitlab-ci.yml
+++ b/src/webui/.gitlab-ci.yml
@@ -55,7 +55,9 @@ unit test webui:
     - sleep 5
     - docker ps -a
     - docker logs $IMAGE_NAME
-    - docker exec --user root -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose ${IMAGE_NAME}/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml; coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml; ls -la /opt/results; coverage report --include='${IMAGE_NAME}/*' --show-missing"
+    - docker exec --user root -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
+    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
+    - docker exec --user root -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
     - docker rm -f $IMAGE_NAME
@@ -74,7 +76,7 @@ unit test webui:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
+        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the webui service in Kubernetes Cluster
 deploy webui:
-- 
GitLab


From de767bd98999f4bd2a0607df3ec54962574f6193 Mon Sep 17 00:00:00 2001
From: Sergio <sergio.gonzalez.diaz@atos.net>
Date: Tue, 17 May 2022 19:09:23 +0200
Subject: [PATCH 17/60] Remove cobertura files from .gitlab-ci.yml

---
 src/automation/.gitlab-ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/automation/.gitlab-ci.yml b/src/automation/.gitlab-ci.yml
index 76cd4ea0d..2101255ea 100644
--- a/src/automation/.gitlab-ci.yml
+++ b/src/automation/.gitlab-ci.yml
@@ -69,7 +69,7 @@ unit_test automation:
   coverage: '/JaCoCo Coverage Total: ([0-9]{1,3})%/'
   artifacts:
     reports:
-      cobertura: ${REPORTS_PATH}/cobertura.xml
+      # cobertura: ${REPORTS_PATH}/cobertura.xml
       junit:
         - ${REPORTS_PATH}/surefire-reports/TEST-*.xml
   rules:
-- 
GitLab


From 752303957b7a2901b1eb8189f034cbb9f47d5ae0 Mon Sep 17 00:00:00 2001
From: Sergio <sergio.gonzalez.diaz@atos.net>
Date: Tue, 17 May 2022 19:15:57 +0200
Subject: [PATCH 18/60] Remove cobertura reports from .gitlab-ci.yml files

---
 src/automation/.gitlab-ci.yml                       | 1 -
 src/compute/.gitlab-ci.yml                          | 2 --
 src/context/.gitlab-ci.yml                          | 2 --
 src/dbscanserving/.gitlab-ci.yml                    | 2 --
 src/device/.gitlab-ci.yml                           | 2 --
 src/interdomain/.gitlab-ci.yml                      | 2 --
 src/l3_attackmitigator/.gitlab-ci.yml               | 2 --
 src/l3_centralizedattackdetector/.gitlab-ci.yml     | 2 --
 src/l3_distributedattackdetector/.gitlab-ci.yml     | 2 --
 src/monitoring/.gitlab-ci.yml                       | 2 --
 src/opticalattackmitigator/.gitlab-ci.yml           | 2 --
 src/opticalcentralizedattackdetector/.gitlab-ci.yml | 2 --
 src/service/.gitlab-ci.yml                          | 2 --
 src/webui/.gitlab-ci.yml                            | 2 --
 14 files changed, 27 deletions(-)

diff --git a/src/automation/.gitlab-ci.yml b/src/automation/.gitlab-ci.yml
index 2101255ea..87d141d5b 100644
--- a/src/automation/.gitlab-ci.yml
+++ b/src/automation/.gitlab-ci.yml
@@ -69,7 +69,6 @@ unit_test automation:
   coverage: '/JaCoCo Coverage Total: ([0-9]{1,3})%/'
   artifacts:
     reports:
-      # cobertura: ${REPORTS_PATH}/cobertura.xml
       junit:
         - ${REPORTS_PATH}/surefire-reports/TEST-*.xml
   rules:
diff --git a/src/compute/.gitlab-ci.yml b/src/compute/.gitlab-ci.yml
index 3eb86b9d9..3c6f7b241 100644
--- a/src/compute/.gitlab-ci.yml
+++ b/src/compute/.gitlab-ci.yml
@@ -56,7 +56,6 @@ unit test compute:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -76,7 +75,6 @@ unit test compute:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy compute:
diff --git a/src/context/.gitlab-ci.yml b/src/context/.gitlab-ci.yml
index 3d053036e..dc302cbd3 100644
--- a/src/context/.gitlab-ci.yml
+++ b/src/context/.gitlab-ci.yml
@@ -58,7 +58,6 @@ unit test context:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -79,7 +78,6 @@ unit test context:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy context:
diff --git a/src/dbscanserving/.gitlab-ci.yml b/src/dbscanserving/.gitlab-ci.yml
index 1f2158384..fd0d66bac 100644
--- a/src/dbscanserving/.gitlab-ci.yml
+++ b/src/dbscanserving/.gitlab-ci.yml
@@ -56,7 +56,6 @@ unit test dbscanserving:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -76,7 +75,6 @@ unit test dbscanserving:
     when: always
     reports:
       junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-      # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 
 # Deployment of the dbscanserving service in Kubernetes Cluster
diff --git a/src/device/.gitlab-ci.yml b/src/device/.gitlab-ci.yml
index d58d5f1f3..90f00f7a1 100644
--- a/src/device/.gitlab-ci.yml
+++ b/src/device/.gitlab-ci.yml
@@ -55,7 +55,6 @@ unit test device:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +74,6 @@ unit test device:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy device:
diff --git a/src/interdomain/.gitlab-ci.yml b/src/interdomain/.gitlab-ci.yml
index f3958d07e..a91f9e4ed 100644
--- a/src/interdomain/.gitlab-ci.yml
+++ b/src/interdomain/.gitlab-ci.yml
@@ -55,7 +55,6 @@ unit test service:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +74,6 @@ unit test service:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy service:
diff --git a/src/l3_attackmitigator/.gitlab-ci.yml b/src/l3_attackmitigator/.gitlab-ci.yml
index d9f7fe5d7..28d5ad4cf 100644
--- a/src/l3_attackmitigator/.gitlab-ci.yml
+++ b/src/l3_attackmitigator/.gitlab-ci.yml
@@ -55,7 +55,6 @@ unit test l3_attackmitigator:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +74,6 @@ unit test l3_attackmitigator:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy l3_attackmitigator:
diff --git a/src/l3_centralizedattackdetector/.gitlab-ci.yml b/src/l3_centralizedattackdetector/.gitlab-ci.yml
index c9c461c81..ca95af881 100644
--- a/src/l3_centralizedattackdetector/.gitlab-ci.yml
+++ b/src/l3_centralizedattackdetector/.gitlab-ci.yml
@@ -55,7 +55,6 @@ unit test l3_centralizedattackdetector:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +74,6 @@ unit test l3_centralizedattackdetector:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy l3_centralizedattackdetector:
diff --git a/src/l3_distributedattackdetector/.gitlab-ci.yml b/src/l3_distributedattackdetector/.gitlab-ci.yml
index 175efe81e..7ced7a62c 100644
--- a/src/l3_distributedattackdetector/.gitlab-ci.yml
+++ b/src/l3_distributedattackdetector/.gitlab-ci.yml
@@ -55,7 +55,6 @@ unit test l3_distributedattackdetector:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +74,6 @@ unit test l3_distributedattackdetector:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy l3_distributedattackdetector:
diff --git a/src/monitoring/.gitlab-ci.yml b/src/monitoring/.gitlab-ci.yml
index 2496d0288..61aec5fb3 100644
--- a/src/monitoring/.gitlab-ci.yml
+++ b/src/monitoring/.gitlab-ci.yml
@@ -58,7 +58,6 @@ unit test monitoring:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -79,7 +78,6 @@ unit test monitoring:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
  
 # Deployment of the service in Kubernetes Cluster
 deploy monitoring:
diff --git a/src/opticalattackmitigator/.gitlab-ci.yml b/src/opticalattackmitigator/.gitlab-ci.yml
index f1d69e02f..5b9a133bd 100644
--- a/src/opticalattackmitigator/.gitlab-ci.yml
+++ b/src/opticalattackmitigator/.gitlab-ci.yml
@@ -55,7 +55,6 @@ unit test opticalattackmitigator:
     - sleep 5
     - docker ps -a
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +74,6 @@ unit test opticalattackmitigator:
     when: always
     reports:
       junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-      # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 
 # Deployment of the opticalattackmitigator service in Kubernetes Cluster
diff --git a/src/opticalcentralizedattackdetector/.gitlab-ci.yml b/src/opticalcentralizedattackdetector/.gitlab-ci.yml
index 7deaf0af3..c3d91aec6 100644
--- a/src/opticalcentralizedattackdetector/.gitlab-ci.yml
+++ b/src/opticalcentralizedattackdetector/.gitlab-ci.yml
@@ -55,7 +55,6 @@ unit test opticalcentralizedattackdetector:
     - sleep 5
     - docker ps -a
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +74,6 @@ unit test opticalcentralizedattackdetector:
     when: always
     reports:
       junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-      # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 
 # Deployment of the opticalcentralizedattackdetector service in Kubernetes Cluster
diff --git a/src/service/.gitlab-ci.yml b/src/service/.gitlab-ci.yml
index f3958d07e..a91f9e4ed 100644
--- a/src/service/.gitlab-ci.yml
+++ b/src/service/.gitlab-ci.yml
@@ -55,7 +55,6 @@ unit test service:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -75,7 +74,6 @@ unit test service:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the service in Kubernetes Cluster
 deploy service:
diff --git a/src/webui/.gitlab-ci.yml b/src/webui/.gitlab-ci.yml
index 23a656b1f..c5d3b5056 100644
--- a/src/webui/.gitlab-ci.yml
+++ b/src/webui/.gitlab-ci.yml
@@ -56,7 +56,6 @@ unit test webui:
     - docker ps -a
     - docker logs $IMAGE_NAME
     - docker exec --user root -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec -i $IMAGE_NAME bash -c "coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml"
     - docker exec --user root -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
@@ -76,7 +75,6 @@ unit test webui:
       when: always
       reports:
         junit: src/$IMAGE_NAME/tests/${IMAGE_NAME}_report.xml
-        # cobertura: src/$IMAGE_NAME/tests/${IMAGE_NAME}_coverage.xml
 
 # Deployment of the webui service in Kubernetes Cluster
 deploy webui:
-- 
GitLab


From 561dd0efb41119b35ba26461ddbf1dc3a0292c00 Mon Sep 17 00:00:00 2001
From: Sergio <sergio.gonzalez.diaz@atos.net>
Date: Wed, 18 May 2022 10:38:44 +0200
Subject: [PATCH 19/60] Fix cobertura issues

---
 src/compute/.gitlab-ci.yml | 2 +-
 src/webui/.gitlab-ci.yml   | 5 +++--
 2 files changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/compute/.gitlab-ci.yml b/src/compute/.gitlab-ci.yml
index 3c6f7b241..f3d7c0f30 100644
--- a/src/compute/.gitlab-ci.yml
+++ b/src/compute/.gitlab-ci.yml
@@ -63,7 +63,7 @@ unit test compute:
     - docker network rm teraflowbridge
   rules:
     - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
-    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"' 
+    - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
     - changes:
       - src/$IMAGE_NAME/**/*.{py,in,yml}
       - src/$IMAGE_NAME/Dockerfile
diff --git a/src/webui/.gitlab-ci.yml b/src/webui/.gitlab-ci.yml
index c5d3b5056..45b950d19 100644
--- a/src/webui/.gitlab-ci.yml
+++ b/src/webui/.gitlab-ci.yml
@@ -55,8 +55,9 @@ unit test webui:
     - sleep 5
     - docker ps -a
     - docker logs $IMAGE_NAME
-    - docker exec --user root -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    - docker exec --user root -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
+    - docker exec --user root -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose ${IMAGE_NAME}/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml; coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml; ls -la /opt/results; coverage report --include='${IMAGE_NAME}/*' --show-missing"
+    # - docker exec --user root -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
+    # - docker exec --user root -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
     - docker rm -f $IMAGE_NAME
-- 
GitLab


From b229cc6547aca862803dfa46d01b2f1294001812 Mon Sep 17 00:00:00 2001
From: Sergio <sergio.gonzalez.diaz@atos.net>
Date: Wed, 18 May 2022 10:47:56 +0200
Subject: [PATCH 20/60] Fix cobertura in .gitlab-ci.yml

---
 src/webui/.gitlab-ci.yml | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/src/webui/.gitlab-ci.yml b/src/webui/.gitlab-ci.yml
index 45b950d19..3865541d0 100644
--- a/src/webui/.gitlab-ci.yml
+++ b/src/webui/.gitlab-ci.yml
@@ -55,9 +55,8 @@ unit test webui:
     - sleep 5
     - docker ps -a
     - docker logs $IMAGE_NAME
-    - docker exec --user root -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose ${IMAGE_NAME}/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml; coverage xml -o /opt/results/${IMAGE_NAME}_coverage.xml; ls -la /opt/results; coverage report --include='${IMAGE_NAME}/*' --show-missing"
-    # - docker exec --user root -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
-    # - docker exec --user root -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
+    - docker exec --user root -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=DEBUG --verbose ${IMAGE_NAME}/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
+    - docker exec --user root -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
     - docker rm -f $IMAGE_NAME
-- 
GitLab


From b56f687061e29f1135209cf0d0bab61f1ba0924e Mon Sep 17 00:00:00 2001
From: Sergio <sergio.gonzalez.diaz@atos.net>
Date: Wed, 18 May 2022 17:07:24 +0200
Subject: [PATCH 21/60] Fix cobertura issues in .gitlab-ci.yml

---
 .gitlab-ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 668b5ce62..e47c3f461 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -34,7 +34,7 @@ include:
   - local: '/src/opticalattackmitigator/.gitlab-ci.yml'
   - local: '/src/opticalcentralizedattackdetector/.gitlab-ci.yml'
   - local: '/src/automation/.gitlab-ci.yml'
-  - local: '/src/webui/.gitlab-ci.yml'
+  #- local: '/src/webui/.gitlab-ci.yml'
   #- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml'
   #- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml'
   #- local: '/src/l3_attackmitigator/.gitlab-ci.yml'
-- 
GitLab


From 0eaab40bc4e062bbf6a48bcb54110196d01825cc Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 16:17:49 +0200
Subject: [PATCH 22/60] Scripts: - relocated/renamed wrongly placed/named
 scripts - removed unneeded scripts - added missing headers in scripts

---
 report_coverage_slice.sh                                 | 3 ---
 ...n_tests_in_kubernetes.sh => report_coverage_slice.sh} | 9 +--------
 2 files changed, 1 insertion(+), 11 deletions(-)
 delete mode 100755 report_coverage_slice.sh
 rename scripts/{run_tests_in_kubernetes.sh => report_coverage_slice.sh} (61%)

diff --git a/report_coverage_slice.sh b/report_coverage_slice.sh
deleted file mode 100755
index f783ec069..000000000
--- a/report_coverage_slice.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/bash
-
-./report_coverage_all.sh | grep --color -E -i "^slice/.*$|$"
diff --git a/scripts/run_tests_in_kubernetes.sh b/scripts/report_coverage_slice.sh
similarity index 61%
rename from scripts/run_tests_in_kubernetes.sh
rename to scripts/report_coverage_slice.sh
index fc0e14257..f9b17e8bd 100755
--- a/scripts/run_tests_in_kubernetes.sh
+++ b/scripts/report_coverage_slice.sh
@@ -14,11 +14,4 @@
 # limitations under the License.
 
 
-IMAGE_NAME='integration_tester'
-IMAGE_TAG='latest'
-CI_REGISTRY_IMAGE='registry.gitlab.com/teraflow-h2020/controller'
-
-kubectl delete pod $(echo $IMAGE_NAME | sed -r 's/[^a-zA-Z0-9\.\-]/-/g') --wait=true --ignore-not-found=true
-kubectl get all
-kubectl run $(echo $IMAGE_NAME | sed -r 's/[^a-zA-Z0-9\.\-]/-/g') --image "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG" --restart=Never --rm -i
-kubectl get all
+./report_coverage_all.sh | grep --color -E -i "^slice/.*$|$"
-- 
GitLab


From 5dc77fe4c81b1455c227f0d3d51836153800bb39 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 16:21:59 +0200
Subject: [PATCH 23/60] Common framework: - defined unified constants for all
 micro-services - defined common settings getter methods - defined generic
 gRPC servicer - defined generic Rest servicer - defined common MockServicer
 for Monitoring component - removed old common/tests MockService class; to be
 replaced by new generic gRPC servicer - minor code formatting/styling

---
 src/common/Constants.py                       | 59 +++++++++++++++
 src/common/Settings.py                        | 63 +++++++++++++++-
 src/common/tests/MockService.py               | 55 --------------
 .../tests/MockServicerImpl_Monitoring.py      | 34 +++++++++
 src/common/tools/object_factory/Device.py     |  2 +-
 .../tools/service/GenericGrpcService.py       | 71 +++++++++++++++++++
 src/common/tools/service/GenericRestServer.py | 59 +++++++++++++++
 src/common/tools/service/__init__.py          | 14 ++++
 8 files changed, 299 insertions(+), 58 deletions(-)
 delete mode 100644 src/common/tests/MockService.py
 create mode 100644 src/common/tests/MockServicerImpl_Monitoring.py
 create mode 100644 src/common/tools/service/GenericGrpcService.py
 create mode 100644 src/common/tools/service/GenericRestServer.py
 create mode 100644 src/common/tools/service/__init__.py

diff --git a/src/common/Constants.py b/src/common/Constants.py
index 9d5edc235..dbe4124e7 100644
--- a/src/common/Constants.py
+++ b/src/common/Constants.py
@@ -12,5 +12,64 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+import logging
+from enum import Enum
+
+# Default logging level
+DEFAULT_LOG_LEVEL = logging.WARNING
+
+# Default gRPC server settings
+DEFAULT_GRPC_BIND_ADDRESS = '0.0.0.0'
+DEFAULT_GRPC_MAX_WORKERS  = 10
+DEFAULT_GRPC_GRACE_PERIOD = 60
+
+# Default HTTP server settings
+DEFAULT_HTTP_BIND_ADDRESS = '0.0.0.0'
+
+# Default Prometheus settings
+DEFAULT_METRICS_PORT = 9192
+
+# Default context and topology UUIDs
 DEFAULT_CONTEXT_UUID = 'admin'
 DEFAULT_TOPOLOGY_UUID = 'admin'
+
+# Default service names
+class ServiceNameEnum(Enum):
+    CONTEXT       = 'context'
+    DEVICE        = 'device'
+    SERVICE       = 'service'
+    SLICE         = 'slice'
+    AUTOMATION    = 'automation'
+    POLICY        = 'policy'
+    MONITORING    = 'monitoring'
+    DLT           = 'dlt'
+    COMPUTE       = 'compute'
+    CYBERSECURITY = 'cybersecurity'
+    INTERDOMAIN   = 'interdomain'
+
+# Default gRPC service ports
+DEFAULT_SERVICE_GRPC_PORTS = {
+    ServiceNameEnum.CONTEXT      .value :  1010,
+    ServiceNameEnum.DEVICE       .value :  2020,
+    ServiceNameEnum.SERVICE      .value :  3030,
+    ServiceNameEnum.SLICE        .value :  4040,
+    ServiceNameEnum.AUTOMATION   .value :  5050,
+    ServiceNameEnum.POLICY       .value :  6060,
+    ServiceNameEnum.MONITORING   .value :  7070,
+    ServiceNameEnum.DLT          .value :  8080,
+    ServiceNameEnum.COMPUTE      .value :  9090,
+    ServiceNameEnum.CYBERSECURITY.value : 10000,
+    ServiceNameEnum.INTERDOMAIN  .value : 10010,
+}
+
+# Default HTTP/REST-API service ports
+DEFAULT_SERVICE_HTTP_PORTS = {
+    ServiceNameEnum.CONTEXT   .value : 8080,
+    ServiceNameEnum.COMPUTE   .value : 8080,
+}
+
+# Default HTTP/REST-API service base URLs
+DEFAULT_SERVICE_HTTP_BASEURLS = {
+    ServiceNameEnum.CONTEXT   .value : '/api',
+    ServiceNameEnum.COMPUTE   .value : '/restconf/data',
+}
diff --git a/src/common/Settings.py b/src/common/Settings.py
index f6bc214bf..e9d5f406d 100644
--- a/src/common/Settings.py
+++ b/src/common/Settings.py
@@ -14,15 +14,33 @@
 
 import logging, os, time
 from typing import List
+from common.Constants import (
+    DEFAULT_GRPC_BIND_ADDRESS, DEFAULT_GRPC_GRACE_PERIOD, DEFAULT_GRPC_MAX_WORKERS, DEFAULT_HTTP_BIND_ADDRESS,
+    DEFAULT_LOG_LEVEL, DEFAULT_METRICS_PORT, DEFAULT_SERVICE_GRPC_PORTS, DEFAULT_SERVICE_HTTP_BASEURLS,
+    DEFAULT_SERVICE_HTTP_PORTS, ServiceNameEnum
+)
 
 LOGGER = logging.getLogger(__name__)
 
 DEFAULT_RESTART_DELAY = 5.0 # seconds
 
+ENVVAR_KUBERNETES_PORT            = 'KUBERNETES_PORT'
+ENVVAR_GRPC_BIND_ADDRESS          = 'GRPC_BIND_ADDRESS'
+ENVVAR_GRPC_MAX_WORKERS           = 'GRPC_MAX_WORKERS'
+ENVVAR_GRPC_GRACE_PERIOD          = 'GRPC_GRACE_PERIOD'
+ENVVAR_HTTP_BIND_ADDRESS          = 'HTTP_BIND_ADDRESS'
+ENVVAR_LOG_LEVEL                  = 'LOG_LEVEL'
+ENVVAR_METRICS_PORT               = 'METRICS_PORT'
+
+ENVVAR_SUFIX_SERVICE_BASEURL_HTTP = 'SERVICE_BASEURL_HTTP'
+ENVVAR_SUFIX_SERVICE_HOST         = 'SERVICE_HOST'
+ENVVAR_SUFIX_SERVICE_PORT_GRPC    = 'SERVICE_PORT_GRPC'
+ENVVAR_SUFIX_SERVICE_PORT_HTTP    = 'SERVICE_PORT_HTTP'
+
 def wait_for_environment_variables(
     required_environment_variables : List[str] = [], wait_delay_seconds : float = DEFAULT_RESTART_DELAY
 ):
-    if 'KUBERNETES_PORT' not in os.environ: return # We're not running in Kubernetes, nothing to wait for
+    if ENVVAR_KUBERNETES_PORT not in os.environ: return # We're not running in Kubernetes, nothing to wait for
     missing_variables = set(required_environment_variables).difference(set(os.environ.keys()))
     if len(missing_variables) == 0: return # We have all environment variables defined
     msg = 'Variables({:s}) are missing in Environment({:s}), restarting in {:f} seconds...'
@@ -36,4 +54,45 @@ def get_setting(name, **kwargs):
         value = kwargs['settings'].pop(name, value)
     if value is not None: return value
     if 'default' in kwargs: return kwargs['default']
-    raise Exception('Setting({}) not specified in environment or configuration'.format(name))
+    raise Exception('Setting({:s}) not specified in environment or configuration'.format(str(name)))
+
+def get_env_var_name(service_name : ServiceNameEnum, env_var_group):
+    return ('{:s}SERVICE_{:s}'.format(service_name.value, env_var_group)).upper()
+
+def get_service_host(service_name : ServiceNameEnum):
+    envvar_name = get_env_var_name(service_name, ENVVAR_SUFIX_SERVICE_HOST)
+    default_value = ('{:s}service'.format(service_name.value))
+    return get_setting(envvar_name, default=default_value)
+
+def get_service_port_grpc(service_name : ServiceNameEnum):
+    envvar_name = get_env_var_name(service_name, ENVVAR_SUFIX_SERVICE_PORT_GRPC)
+    default_value = DEFAULT_SERVICE_GRPC_PORTS.get(service_name.value)
+    return get_setting(envvar_name, default=default_value)
+
+def get_service_port_http(service_name : ServiceNameEnum):
+    envvar_name = get_env_var_name(service_name, ENVVAR_SUFIX_SERVICE_PORT_HTTP)
+    default_value = DEFAULT_SERVICE_HTTP_PORTS.get(service_name.value)
+    return get_setting(envvar_name, default=default_value)
+
+def get_service_baseurl_http(service_name : ServiceNameEnum):
+    envvar_name = get_env_var_name(service_name, ENVVAR_SUFIX_SERVICE_BASEURL_HTTP)
+    default_value = DEFAULT_SERVICE_HTTP_BASEURLS.get(service_name.value)
+    return get_setting(envvar_name, default=default_value)
+
+def get_log_level():
+    return get_setting(ENVVAR_LOG_LEVEL, default=DEFAULT_LOG_LEVEL)
+
+def get_metrics_port():
+    return get_setting(ENVVAR_METRICS_PORT, default=DEFAULT_METRICS_PORT)
+
+def get_grpc_bind_address():
+    return get_setting(ENVVAR_GRPC_BIND_ADDRESS, default=DEFAULT_GRPC_BIND_ADDRESS)
+
+def get_grpc_max_workers():
+    return get_setting(ENVVAR_GRPC_MAX_WORKERS, default=DEFAULT_GRPC_MAX_WORKERS)
+
+def get_grpc_grace_period():
+    return get_setting(ENVVAR_GRPC_GRACE_PERIOD, default=DEFAULT_GRPC_GRACE_PERIOD)
+
+def get_http_bind_address():
+    return get_setting(ENVVAR_HTTP_BIND_ADDRESS, default=DEFAULT_HTTP_BIND_ADDRESS)
diff --git a/src/common/tests/MockService.py b/src/common/tests/MockService.py
deleted file mode 100644
index 25f36e009..000000000
--- a/src/common/tests/MockService.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import grpc, logging
-from concurrent import futures
-
-GRPC_MAX_WORKERS  = 10
-GRPC_GRACE_PERIOD = 60
-
-class MockService:
-    def __init__(self, address, port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD, cls_name=__name__):
-        self.logger = logging.getLogger(cls_name)
-        self.address = address
-        self.port = port
-        self.endpoint = None
-        self.max_workers = max_workers
-        self.grace_period = grace_period
-        self.pool = None
-        self.server = None
-
-    def install_servicers(self):
-        pass
-
-    def start(self):
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
-        self.logger.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
-            str(self.endpoint), str(self.max_workers)))
-
-        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
-        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
-
-        self.install_servicers()
-
-        port = self.server.add_insecure_port(self.endpoint)
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
-        self.logger.info('Listening on {:s}...'.format(str(self.endpoint)))
-        self.server.start()
-
-        self.logger.debug('Service started')
-
-    def stop(self):
-        self.logger.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
-        self.server.stop(self.grace_period)
-        self.logger.debug('Service stopped')
diff --git a/src/common/tests/MockServicerImpl_Monitoring.py b/src/common/tests/MockServicerImpl_Monitoring.py
new file mode 100644
index 000000000..9f646c366
--- /dev/null
+++ b/src/common/tests/MockServicerImpl_Monitoring.py
@@ -0,0 +1,34 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+import grpc, logging
+from queue import Queue
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from monitoring.proto.context_pb2 import Empty
+from monitoring.proto.monitoring_pb2 import Kpi
+from monitoring.proto.monitoring_pb2_grpc import MonitoringServiceServicer
+
+LOGGER = logging.getLogger(__name__)
+
+class MockServicerImpl_Monitoring(MonitoringServiceServicer):
+    def __init__(self, queue_samples : Queue):
+        LOGGER.info('[__init__] Creating Servicer...')
+        self.queue_samples = queue_samples
+        LOGGER.info('[__init__] Servicer Created')
+
+    def IncludeKpi(self, request : Kpi, context : grpc.ServicerContext) -> Empty:
+        LOGGER.info('[IncludeKpi] request={:s}'.format(grpc_message_to_json_string(request)))
+        self.queue_samples.put(request)
+        return Empty()
diff --git a/src/common/tools/object_factory/Device.py b/src/common/tools/object_factory/Device.py
index d5990db5e..e144b5b4c 100644
--- a/src/common/tools/object_factory/Device.py
+++ b/src/common/tools/object_factory/Device.py
@@ -20,8 +20,8 @@ from context.proto.context_pb2 import DeviceDriverEnum, DeviceOperationalStatusE
 
 DEVICE_DISABLED = DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED
 
+DEVICE_EMUOLS_TYPE  = DeviceTypeEnum.EMULATED_OPTICAL_LINE_SYSTEM.value
 DEVICE_EMUPR_TYPE   = DeviceTypeEnum.EMULATED_PACKET_ROUTER.value
-DEVICE_EMUOLS_TYPE   = DeviceTypeEnum.EMULATED_OPTICAL_LINE_SYSTEM.value
 DEVICE_EMU_DRIVERS  = [DeviceDriverEnum.DEVICEDRIVER_UNDEFINED]
 DEVICE_EMU_ADDRESS  = '127.0.0.1'
 DEVICE_EMU_PORT     = '0'
diff --git a/src/common/tools/service/GenericGrpcService.py b/src/common/tools/service/GenericGrpcService.py
new file mode 100644
index 000000000..61fccdb02
--- /dev/null
+++ b/src/common/tools/service/GenericGrpcService.py
@@ -0,0 +1,71 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from typing import Optional, Union
+import grpc, logging
+from concurrent import futures
+from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
+from grpc_health.v1.health_pb2 import HealthCheckResponse
+from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
+from common.Settings import get_grpc_bind_address, get_grpc_grace_period, get_grpc_max_workers
+
+class GenericGrpcService:
+    def __init__(
+        self, bind_port : Union[str, int], bind_address : Optional[str] = None, max_workers : Optional[int] = None,
+        grace_period : Optional[int] = None, enable_health_servicer : bool = True, cls_name : str = __name__
+    ) -> None:
+        self.logger = logging.getLogger(cls_name)
+        self.bind_port = bind_port
+        self.bind_address = get_grpc_bind_address() if bind_address is None else bind_address
+        self.max_workers = get_grpc_max_workers() if max_workers is None else max_workers
+        self.grace_period = get_grpc_grace_period() if grace_period is None else grace_period
+        self.enable_health_servicer = enable_health_servicer
+        self.endpoint = None
+        self.health_servicer = None
+        self.pool = None
+        self.server = None
+
+    def install_servicers(self):
+        pass
+
+    def start(self):
+        self.endpoint = '{:s}:{:s}'.format(str(self.bind_address), str(self.bind_port))
+        self.logger.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
+            str(self.endpoint), str(self.max_workers)))
+
+        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
+        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
+
+        self.install_servicers()
+
+        if self.enable_health_servicer:
+            self.health_servicer = HealthServicer(
+                experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
+            add_HealthServicer_to_server(self.health_servicer, self.server)
+
+        self.bind_port = self.server.add_insecure_port(self.endpoint)
+        self.endpoint = '{:s}:{:s}'.format(str(self.bind_address), str(self.bind_port))
+        self.logger.info('Listening on {:s}...'.format(str(self.endpoint)))
+        self.server.start()
+        if self.enable_health_servicer:
+            self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
+
+        self.logger.debug('Service started')
+
+    def stop(self):
+        self.logger.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
+        if self.enable_health_servicer:
+            self.health_servicer.enter_graceful_shutdown()
+        self.server.stop(self.grace_period)
+        self.logger.debug('Service stopped')
diff --git a/src/common/tools/service/GenericRestServer.py b/src/common/tools/service/GenericRestServer.py
new file mode 100644
index 000000000..4325fe1db
--- /dev/null
+++ b/src/common/tools/service/GenericRestServer.py
@@ -0,0 +1,59 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import functools, logging, threading, time
+from typing import Optional, Union
+from flask import Flask, request
+from flask_restful import Api, Resource
+from werkzeug.serving import make_server
+from common.Settings import get_http_bind_address
+
+logging.getLogger('werkzeug').setLevel(logging.WARNING)
+
+
+def log_request(logger, response):
+    timestamp = time.strftime('[%Y-%b-%d %H:%M]')
+    logger.info('%s %s %s %s %s', timestamp, request.remote_addr, request.method, request.full_path, response.status)
+    return response
+
+class GenericRestServer(threading.Thread):
+    def __init__(
+        self, bind_port : Union[str, int], base_url : str, bind_address : Optional[str] = None,
+        cls_name : str = __name__
+    ) -> None:
+        threading.Thread.__init__(self, daemon=True)
+        self.logger = logging.getLogger(cls_name)
+        self.bind_port = bind_port
+        self.base_url = base_url
+        self.bind_address = get_http_bind_address() if bind_address is None else bind_address
+        self.endpoint = 'http://{:s}:{:s}{:s}'.format(str(self.bind_address), str(self.bind_port), str(self.base_url))
+        self.srv = None
+        self.ctx = None
+        self.app = Flask(__name__)
+        self.app.after_request(functools.partial(log_request, self.logger))
+        self.api = Api(self.app, prefix=self.base_url)
+
+    def add_resource(self, resource : Resource, *urls, **kwargs):
+        self.api.add_resource(resource, *urls, **kwargs)
+
+    def run(self):
+        self.srv = make_server(self.bind_address, self.bind_port, self.app, threaded=True)
+        self.ctx = self.app.app_context()
+        self.ctx.push()
+
+        self.logger.info('Listening on {:s}...'.format(str(self.endpoint)))
+        self.srv.serve_forever()
+
+    def shutdown(self):
+        self.srv.shutdown()
diff --git a/src/common/tools/service/__init__.py b/src/common/tools/service/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/common/tools/service/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
-- 
GitLab


From 11a69c44d3b4c00d85a83c2ad127ffe9e68a0be8 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 16:25:22 +0200
Subject: [PATCH 24/60] Context component: - Migrated to use new generic gRPC
 servicer - Migrated to use new generic Rest servicer - Migrated to use new
 settings framework

---
 src/context/Config.py                         | 17 -----
 src/context/client/ContextClient.py           | 12 ++--
 src/context/service/Populate.py               |  4 +-
 src/context/service/__main__.py               | 29 +++------
 .../service/grpc_server/ContextService.py     | 65 ++++---------------
 src/context/service/rest_server/RestServer.py | 23 +++++++
 src/context/service/rest_server/Server.py     | 50 --------------
 src/context/tests/test_unitary.py             | 31 +++++----
 8 files changed, 73 insertions(+), 158 deletions(-)
 create mode 100644 src/context/service/rest_server/RestServer.py
 delete mode 100644 src/context/service/rest_server/Server.py

diff --git a/src/context/Config.py b/src/context/Config.py
index 328610fc8..6f5d1dc0b 100644
--- a/src/context/Config.py
+++ b/src/context/Config.py
@@ -12,22 +12,5 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging
-
-# General settings
-LOG_LEVEL = logging.INFO
-
-# gRPC settings
-GRPC_SERVICE_PORT = 1010
-GRPC_MAX_WORKERS  = 200 # multiple clients might keep connections alive for Get*Events() RPC methods
-GRPC_GRACE_PERIOD = 60
-
-# REST-API settings
-RESTAPI_SERVICE_PORT = 8080
-RESTAPI_BASE_URL = '/api'
-
-# Prometheus settings
-METRICS_PORT = 9192
-
 # Autopopulate the component with fake data for testing purposes?
 POPULATE_FAKE_DATA = False
diff --git a/src/context/client/ContextClient.py b/src/context/client/ContextClient.py
index 3206e4a36..34214fac0 100644
--- a/src/context/client/ContextClient.py
+++ b/src/context/client/ContextClient.py
@@ -12,8 +12,10 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from typing import Iterator
 import grpc, logging
+from typing import Iterator
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_grpc
 from common.tools.client.RetryDecorator import retry, delay_exponential
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.proto.context_pb2 import (
@@ -29,9 +31,11 @@ DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
 RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
 
 class ContextClient:
-    def __init__(self, address, port):
-        self.endpoint = '{:s}:{:s}'.format(str(address), str(port))
-        LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint))
+    def __init__(self, host=None, port=None):
+        if not host: host = get_service_host(ServiceNameEnum.CONTEXT)
+        if not port: port = get_service_port_grpc(ServiceNameEnum.CONTEXT)
+        self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
+        LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint)))
         self.channel = None
         self.stub = None
         self.connect()
diff --git a/src/context/service/Populate.py b/src/context/service/Populate.py
index f4630182d..ace630900 100644
--- a/src/context/service/Populate.py
+++ b/src/context/service/Populate.py
@@ -20,8 +20,8 @@ from context.tests.Objects import (
     LINK_R1_R2, LINK_R1_R2_ID, LINK_R1_R3, LINK_R1_R3_ID, LINK_R2_R3, LINK_R2_R3_ID, SERVICE_R1_R2, SERVICE_R1_R3,
     SERVICE_R2_R3)
 
-def populate(address, port):
-    client = ContextClient(address=address, port=port)
+def populate(host=None, port=None):
+    client = ContextClient(host=host, port=port)
 
     client.SetContext(Context(**CONTEXT))
     client.SetTopology(Topology(**TOPOLOGY))
diff --git a/src/context/service/__main__.py b/src/context/service/__main__.py
index 180a1f44c..53754caf4 100644
--- a/src/context/service/__main__.py
+++ b/src/context/service/__main__.py
@@ -14,17 +14,15 @@
 
 import logging, signal, sys, threading
 from prometheus_client import start_http_server
-from common.Settings import get_setting
+from common.Settings import get_log_level, get_metrics_port, get_setting
 from common.orm.Database import Database
 from common.orm.Factory import get_database_backend
 from common.message_broker.Factory import get_messagebroker_backend
 from common.message_broker.MessageBroker import MessageBroker
-from context.Config import (
-    GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, POPULATE_FAKE_DATA, RESTAPI_SERVICE_PORT,
-    RESTAPI_BASE_URL, METRICS_PORT)
+from context.Config import POPULATE_FAKE_DATA
 from .grpc_server.ContextService import ContextService
 from .rest_server.Resources import RESOURCES
-from .rest_server.Server import Server
+from .rest_server.RestServer import RestServer
 from .Populate import populate
 
 terminate = threading.Event()
@@ -37,16 +35,7 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
 def main():
     global LOGGER # pylint: disable=global-statement
 
-    grpc_service_port    = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT   )
-    max_workers          = get_setting('MAX_WORKERS',                      default=GRPC_MAX_WORKERS    )
-    grace_period         = get_setting('GRACE_PERIOD',                     default=GRPC_GRACE_PERIOD   )
-    log_level            = get_setting('LOG_LEVEL',                        default=LOG_LEVEL           )
-    restapi_service_port = get_setting('CONTEXTSERVICE_SERVICE_PORT_HTTP', default=RESTAPI_SERVICE_PORT)
-    restapi_base_url     = get_setting('RESTAPI_BASE_URL',                 default=RESTAPI_BASE_URL    )
-    metrics_port         = get_setting('METRICS_PORT',                     default=METRICS_PORT        )
-    populate_fake_data   = get_setting('POPULATE_FAKE_DATA',               default=POPULATE_FAKE_DATA  )
-    if isinstance(populate_fake_data, str): populate_fake_data = (populate_fake_data.upper() in {'T', '1', 'TRUE'})
-
+    log_level = get_log_level()
     logging.basicConfig(level=log_level)
     LOGGER = logging.getLogger(__name__)
 
@@ -56,6 +45,7 @@ def main():
     LOGGER.info('Starting...')
 
     # Start metrics server
+    metrics_port = get_metrics_port()
     start_http_server(metrics_port)
 
     # Get database instance
@@ -65,18 +55,19 @@ def main():
     messagebroker = MessageBroker(get_messagebroker_backend())
 
     # Starting context service
-    grpc_service = ContextService(
-        database, messagebroker, port=grpc_service_port, max_workers=max_workers, grace_period=grace_period)
+    grpc_service = ContextService(database, messagebroker)
     grpc_service.start()
 
-    rest_server = Server(port=restapi_service_port, base_url=restapi_base_url)
+    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()
 
+    populate_fake_data = get_setting('POPULATE_FAKE_DATA', default=POPULATE_FAKE_DATA)
+    if isinstance(populate_fake_data, str): populate_fake_data = (populate_fake_data.upper() in {'T', '1', 'TRUE'})
     if populate_fake_data:
         LOGGER.info('Populating fake data...')
-        populate('127.0.0.1', grpc_service_port)
+        populate(host='127.0.0.1', port=grpc_service.bind_port)
         LOGGER.info('Fake Data populated')
 
     # Wait for Ctrl+C or termination signal
diff --git a/src/context/service/grpc_server/ContextService.py b/src/context/service/grpc_server/ContextService.py
index 87ca94a70..c338b0f0d 100644
--- a/src/context/service/grpc_server/ContextService.py
+++ b/src/context/service/grpc_server/ContextService.py
@@ -12,61 +12,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import grpc
-import logging
-from concurrent import futures
-from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
-from grpc_health.v1.health_pb2 import HealthCheckResponse
-from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
-from context.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_port_grpc
+from common.message_broker.MessageBroker import MessageBroker
+from common.orm.Database import Database
+from common.tools.service.GenericGrpcService import GenericGrpcService
 from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server
 from .ContextServiceServicerImpl import ContextServiceServicerImpl
 
-BIND_ADDRESS = '0.0.0.0'
-LOGGER = logging.getLogger(__name__)
+# Custom gRPC settings
+GRPC_MAX_WORKERS = 200 # multiple clients might keep connections alive for Get*Events() RPC methods
 
-class ContextService:
-    def __init__(
-        self, database, messagebroker, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS,
-        grace_period=GRPC_GRACE_PERIOD):
+class ContextService(GenericGrpcService):
+    def __init__(self, database : Database, messagebroker : MessageBroker, cls_name: str = __name__) -> None:
+        port = get_service_port_grpc(ServiceNameEnum.CONTEXT)
+        super().__init__(port, max_workers=GRPC_MAX_WORKERS, cls_name=cls_name)
+        self.context_servicer = ContextServiceServicerImpl(database, messagebroker)
 
-        self.database = database
-        self.messagebroker = messagebroker
-        self.address = address
-        self.port = port
-        self.endpoint = None
-        self.max_workers = max_workers
-        self.grace_period = grace_period
-        self.context_servicer = None
-        self.health_servicer = None
-        self.pool = None
-        self.server = None
-
-    def start(self):
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
-        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
-            str(self.endpoint), str(self.max_workers)))
-
-        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
-        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
-
-        self.context_servicer = ContextServiceServicerImpl(self.database, self.messagebroker)
+    def install_servicers(self):
         add_ContextServiceServicer_to_server(self.context_servicer, self.server)
-
-        self.health_servicer = HealthServicer(
-            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
-        add_HealthServicer_to_server(self.health_servicer, self.server)
-
-        port = self.server.add_insecure_port(self.endpoint)
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
-        LOGGER.info('Listening on {:s}...'.format(str(self.endpoint)))
-        self.server.start()
-        self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
-
-        LOGGER.debug('Service started')
-
-    def stop(self):
-        LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
-        self.health_servicer.enter_graceful_shutdown()
-        self.server.stop(self.grace_period)
-        LOGGER.debug('Service stopped')
diff --git a/src/context/service/rest_server/RestServer.py b/src/context/service/rest_server/RestServer.py
new file mode 100644
index 000000000..289e92a3c
--- /dev/null
+++ b/src/context/service/rest_server/RestServer.py
@@ -0,0 +1,23 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_baseurl_http, get_service_port_http
+from common.tools.service.GenericRestServer import GenericRestServer
+
+class RestServer(GenericRestServer):
+    def __init__(self, cls_name: str = __name__) -> None:
+        bind_port = get_service_port_http(ServiceNameEnum.CONTEXT)
+        base_url = get_service_baseurl_http(ServiceNameEnum.CONTEXT)
+        super().__init__(bind_port, base_url, cls_name=cls_name)
diff --git a/src/context/service/rest_server/Server.py b/src/context/service/rest_server/Server.py
deleted file mode 100644
index ac4888d41..000000000
--- a/src/context/service/rest_server/Server.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import logging, threading
-from flask import Flask
-from flask_restful import Api
-from werkzeug.serving import make_server
-from context.Config import RESTAPI_BASE_URL, RESTAPI_SERVICE_PORT
-
-logging.getLogger('werkzeug').setLevel(logging.WARNING)
-
-BIND_ADDRESS = '0.0.0.0'
-LOGGER = logging.getLogger(__name__)
-
-class Server(threading.Thread):
-    def __init__(self, host=BIND_ADDRESS, port=RESTAPI_SERVICE_PORT, base_url=RESTAPI_BASE_URL):
-        threading.Thread.__init__(self, daemon=True)
-        self.host = host
-        self.port = port
-        self.base_url = base_url
-        self.srv = None
-        self.ctx = None
-        self.app = Flask(__name__)
-        self.api = Api(self.app, prefix=self.base_url)
-
-    def add_resource(self, resource, *urls, **kwargs):
-        self.api.add_resource(resource, *urls, **kwargs)
-
-    def run(self):
-        self.srv = make_server(self.host, self.port, self.app, threaded=True)
-        self.ctx = self.app.app_context()
-        self.ctx.push()
-
-        endpoint = 'http://{:s}:{:s}{:s}'.format(str(self.host), str(self.port), str(self.base_url))
-        LOGGER.info('Listening on {:s}...'.format(str(endpoint)))
-        self.srv.serve_forever()
-
-    def shutdown(self):
-        self.srv.shutdown()
diff --git a/src/context/tests/test_unitary.py b/src/context/tests/test_unitary.py
index 10f44d9ad..870067d1e 100644
--- a/src/context/tests/test_unitary.py
+++ b/src/context/tests/test_unitary.py
@@ -15,7 +15,8 @@
 # pylint: disable=too-many-lines
 import copy, grpc, logging, os, pytest, requests, time, urllib
 from typing import Tuple
-from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID
+from common.Constants import DEFAULT_CONTEXT_UUID, DEFAULT_TOPOLOGY_UUID, ServiceNameEnum
+from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, ENVVAR_SUFIX_SERVICE_PORT_HTTP, get_env_var_name, get_service_baseurl_http, get_service_port_grpc, get_service_port_http
 from common.orm.Database import Database
 from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
 from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
@@ -25,8 +26,6 @@ from common.type_checkers.Assertions import (
     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)
-from context.Config import (
-    GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, RESTAPI_SERVICE_PORT, RESTAPI_BASE_URL)
 from context.client.ContextClient import ContextClient
 from context.client.EventsCollector import EventsCollector
 from context.proto.context_pb2 import (
@@ -37,7 +36,7 @@ from context.service.database.Tools import (
     FASTHASHER_DATA_ACCEPTED_FORMAT, FASTHASHER_ITEM_ACCEPTED_FORMAT, fast_hasher)
 from context.service.grpc_server.ContextService import ContextService
 from context.service.Populate import populate
-from context.service.rest_server.Server import Server as RestServer
+from context.service.rest_server.RestServer import RestServer
 from context.service.rest_server.Resources import RESOURCES
 from .Objects import (
     CONNECTION_R1_R3, CONNECTION_R1_R3_ID, CONNECTION_R1_R3_UUID, CONTEXT, CONTEXT_ID, DEVICE_R1, DEVICE_R1_ID,
@@ -48,10 +47,15 @@ from .Objects import (
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
 
-GRPC_PORT    = 10000 + GRPC_SERVICE_PORT    # avoid privileged ports
-RESTAPI_PORT = 10000 + RESTAPI_SERVICE_PORT # avoid privileged ports
+LOCAL_HOST = '127.0.0.1'
+GRPC_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.CONTEXT)   # avoid privileged ports
+HTTP_PORT = 10000 + get_service_port_http(ServiceNameEnum.CONTEXT)   # avoid privileged ports
 
-DEFAULT_REDIS_SERVICE_HOST = '127.0.0.1'
+os.environ[get_env_var_name(ServiceNameEnum.CONTEXT.value, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
+os.environ[get_env_var_name(ServiceNameEnum.CONTEXT.value, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(GRPC_PORT)
+os.environ[get_env_var_name(ServiceNameEnum.CONTEXT.value, ENVVAR_SUFIX_SERVICE_PORT_HTTP)] = str(HTTP_PORT)
+
+DEFAULT_REDIS_SERVICE_HOST = LOCAL_HOST
 DEFAULT_REDIS_SERVICE_PORT = 6379
 DEFAULT_REDIS_DATABASE_ID  = 0
 
@@ -78,9 +82,7 @@ def context_db_mb(request) -> Tuple[Database, MessageBroker]:
 
 @pytest.fixture(scope='session')
 def context_service_grpc(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
-    _service = ContextService(
-        context_db_mb[0], context_db_mb[1], port=GRPC_PORT, max_workers=GRPC_MAX_WORKERS,
-        grace_period=GRPC_GRACE_PERIOD)
+    _service = ContextService(context_db_mb[0], context_db_mb[1])
     _service.start()
     yield _service
     _service.stop()
@@ -88,7 +90,7 @@ def context_service_grpc(context_db_mb : Tuple[Database, MessageBroker]): # pyli
 @pytest.fixture(scope='session')
 def context_service_rest(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
     database = context_db_mb[0]
-    _rest_server = RestServer(port=RESTAPI_PORT, base_url=RESTAPI_BASE_URL)
+    _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()
@@ -99,12 +101,13 @@ def context_service_rest(context_db_mb : Tuple[Database, MessageBroker]): # pyli
 
 @pytest.fixture(scope='session')
 def context_client_grpc(context_service_grpc : ContextService): # pylint: disable=redefined-outer-name
-    _client = ContextClient(address='127.0.0.1', port=GRPC_PORT)
+    _client = ContextClient()
     yield _client
     _client.close()
 
 def do_rest_request(url : str):
-    request_url = 'http://127.0.0.1:{:s}{:s}{:s}'.format(str(RESTAPI_PORT), str(RESTAPI_BASE_URL), url)
+    base_url = get_service_baseurl_http(ServiceNameEnum.CONTEXT)
+    request_url = 'http://{:s}:{:s}{:s}{:s}'.format(str(LOCAL_HOST), str(HTTP_PORT), str(base_url), url)
     LOGGER.warning('Request: GET {:s}'.format(str(request_url)))
     reply = requests.get(request_url)
     LOGGER.warning('Reply: {:s}'.format(str(reply.text)))
@@ -1172,7 +1175,7 @@ def test_rest_populate_database(
     ):
     database = context_db_mb[0]
     database.clear_all()
-    populate('127.0.0.1', GRPC_PORT)
+    populate(LOCAL_HOST, GRPC_PORT)
 
 def test_rest_get_context_ids(context_service_rest : RestServer): # pylint: disable=redefined-outer-name
     reply = do_rest_request('/context_ids')
-- 
GitLab


From 0ed8cfee4c403d17b66a6ca47075d14a42f2e009 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 16:32:38 +0200
Subject: [PATCH 25/60] Device component: - Migrated to use new generic gRPC
 servicer - Migrated to use new generic Rest servicer - Migrated to use new
 settings framework - Migrated tests to use new generic servicers and mock's -
 Solved bug with endpoint monitors' population (dupplicated sample types due
 to wrong key generation) - Use Emulated driver when both driver and device
 type are not specified - Separated unitary tests and execution scripts per
 device driver - Extracted common unitary test functionalities into separate
 code files - Minor code styling/formatting

---
 scripts/run_tests_locally-device-all.sh       |   40 +
 .../run_tests_locally-device-emulated.sh      |   23 +-
 ... => run_tests_locally-device-microwave.sh} |    2 +-
 .../run_tests_locally-device-openconfig.sh    |   28 +
 ...vice.sh => run_tests_locally-device-p4.sh} |    2 +-
 scripts/run_tests_locally-device-tapi.sh      |   28 +
 src/device/Config.py                          |   18 -
 src/device/client/DeviceClient.py             |   31 +-
 src/device/service/DeviceService.py           |   71 +-
 .../service/DeviceServiceServicerImpl.py      |    7 +-
 src/device/service/MonitoringLoops.py         |   10 +-
 src/device/service/__main__.py                |   43 +-
 src/device/service/database/EndPointModel.py  |   18 +-
 .../service/driver_api/DriverFactory.py       |    1 +
 src/device/service/drivers/__init__.py        |    8 +
 src/device/tests/MockMonitoringService.py     |   61 -
 src/device/tests/MockService_Dependencies.py  |   50 +
 src/device/tests/PrepareTestScenario.py       |   80 ++
 src/device/tests/test_unitary.py              | 1010 -----------------
 src/device/tests/test_unitary_emulated.py     |  378 ++++++
 src/device/tests/test_unitary_microwave.py    |  215 +---
 src/device/tests/test_unitary_openconfig.py   |  299 +++++
 src/device/tests/test_unitary_p4.py           |  146 +++
 src/device/tests/test_unitary_tapi.py         |  167 +++
 24 files changed, 1331 insertions(+), 1405 deletions(-)
 create mode 100755 scripts/run_tests_locally-device-all.sh
 rename src/device/tests/MockMonitoringServiceServicerImpl.py => scripts/run_tests_locally-device-emulated.sh (54%)
 mode change 100644 => 100755
 rename scripts/{run_test_microwave_device.sh => run_tests_locally-device-microwave.sh} (91%)
 create mode 100755 scripts/run_tests_locally-device-openconfig.sh
 rename scripts/{run_tests_locally-device.sh => run_tests_locally-device-p4.sh} (96%)
 create mode 100755 scripts/run_tests_locally-device-tapi.sh
 delete mode 100644 src/device/tests/MockMonitoringService.py
 create mode 100644 src/device/tests/MockService_Dependencies.py
 create mode 100644 src/device/tests/PrepareTestScenario.py
 delete mode 100644 src/device/tests/test_unitary.py
 create mode 100644 src/device/tests/test_unitary_emulated.py
 create mode 100644 src/device/tests/test_unitary_openconfig.py
 create mode 100644 src/device/tests/test_unitary_p4.py
 create mode 100644 src/device/tests/test_unitary_tapi.py

diff --git a/scripts/run_tests_locally-device-all.sh b/scripts/run_tests_locally-device-all.sh
new file mode 100755
index 000000000..2cf8faaf5
--- /dev/null
+++ b/scripts/run_tests_locally-device-all.sh
@@ -0,0 +1,40 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    device/tests/test_unitary_emulated.py
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    device/tests/test_unitary_openconfig.py
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    device/tests/test_unitary_tapi.py
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    device/tests/test_unitary_p4.py
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    device/tests/test_unitary_microwave.py
diff --git a/src/device/tests/MockMonitoringServiceServicerImpl.py b/scripts/run_tests_locally-device-emulated.sh
old mode 100644
new mode 100755
similarity index 54%
rename from src/device/tests/MockMonitoringServiceServicerImpl.py
rename to scripts/run_tests_locally-device-emulated.sh
index 05ca43dda..ab4f77ada
--- a/src/device/tests/MockMonitoringServiceServicerImpl.py
+++ b/scripts/run_tests_locally-device-emulated.sh
@@ -1,3 +1,4 @@
+#!/bin/bash
 # Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
@@ -12,18 +13,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging
-from queue import Queue
-from monitoring.proto.context_pb2 import Empty
-from monitoring.proto.monitoring_pb2 import Kpi
-from monitoring.proto.monitoring_pb2_grpc import MonitoringServiceServicer
 
-LOGGER = logging.getLogger(__name__)
+PROJECTDIR=`pwd`
 
-class MockMonitoringServiceServicerImpl(MonitoringServiceServicer):
-    def __init__(self, queue_samples : Queue):
-        self.queue_samples = queue_samples
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
 
-    def IncludeKpi(self, request : Kpi, context) -> Empty:
-        self.queue_samples.put(request)
-        return Empty()
+# Run unitary tests and analyze coverage of code at same time
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    device/tests/test_unitary_emulated.py
diff --git a/scripts/run_test_microwave_device.sh b/scripts/run_tests_locally-device-microwave.sh
similarity index 91%
rename from scripts/run_test_microwave_device.sh
rename to scripts/run_tests_locally-device-microwave.sh
index 34317b564..e03630c9f 100755
--- a/scripts/run_test_microwave_device.sh
+++ b/scripts/run_tests_locally-device-microwave.sh
@@ -24,5 +24,5 @@ RCFILE=$PROJECTDIR/coverage/.coveragerc
 # Useful flags for pytest:
 #-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
 
-coverage run --rcfile=$RCFILE --append -m pytest -s --log-level=INFO --verbose \
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
     device/tests/test_unitary_microwave.py
diff --git a/scripts/run_tests_locally-device-openconfig.sh b/scripts/run_tests_locally-device-openconfig.sh
new file mode 100755
index 000000000..83d4a0545
--- /dev/null
+++ b/scripts/run_tests_locally-device-openconfig.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    device/tests/test_unitary_openconfig.py
diff --git a/scripts/run_tests_locally-device.sh b/scripts/run_tests_locally-device-p4.sh
similarity index 96%
rename from scripts/run_tests_locally-device.sh
rename to scripts/run_tests_locally-device-p4.sh
index ba6c0b6a5..36b381a3c 100755
--- a/scripts/run_tests_locally-device.sh
+++ b/scripts/run_tests_locally-device-p4.sh
@@ -25,4 +25,4 @@ RCFILE=$PROJECTDIR/coverage/.coveragerc
 #-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
 
 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
-    device/tests/test_unitary.py
+    device/tests/test_unitary_p4.py
diff --git a/scripts/run_tests_locally-device-tapi.sh b/scripts/run_tests_locally-device-tapi.sh
new file mode 100755
index 000000000..a281466b6
--- /dev/null
+++ b/scripts/run_tests_locally-device-tapi.sh
@@ -0,0 +1,28 @@
+#!/bin/bash
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+
+PROJECTDIR=`pwd`
+
+cd $PROJECTDIR/src
+RCFILE=$PROJECTDIR/coverage/.coveragerc
+
+# Run unitary tests and analyze coverage of code at same time
+
+# Useful flags for pytest:
+#-o log_cli=true -o log_file=device.log -o log_file_level=DEBUG
+
+coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
+    device/tests/test_unitary_tapi.py
diff --git a/src/device/Config.py b/src/device/Config.py
index 415ae7b01..70a332512 100644
--- a/src/device/Config.py
+++ b/src/device/Config.py
@@ -12,21 +12,3 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging
-
-# General settings
-LOG_LEVEL = logging.WARNING
-
-# gRPC settings
-GRPC_SERVICE_PORT = 2020
-GRPC_MAX_WORKERS  = 10
-GRPC_GRACE_PERIOD = 60
-
-# Prometheus settings
-METRICS_PORT = 9192
-
-# Dependency micro-service connection settings
-CONTEXT_SERVICE_HOST = '127.0.0.1'
-CONTEXT_SERVICE_PORT = 1010
-MONITORING_SERVICE_HOST = '127.0.0.1'
-MONITORING_SERVICE_PORT = 7070
diff --git a/src/device/client/DeviceClient.py b/src/device/client/DeviceClient.py
index 2a9512411..7fe54cb23 100644
--- a/src/device/client/DeviceClient.py
+++ b/src/device/client/DeviceClient.py
@@ -13,7 +13,10 @@
 # limitations under the License.
 
 import grpc, logging
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_grpc
 from common.tools.client.RetryDecorator import retry, delay_exponential
+from common.tools.grpc.Tools import grpc_message_to_json_string
 from device.proto.context_pb2 import Device, DeviceConfig, DeviceId, Empty
 from device.proto.device_pb2 import MonitoringSettings
 from device.proto.device_pb2_grpc import DeviceServiceStub
@@ -24,8 +27,10 @@ DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
 RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
 
 class DeviceClient:
-    def __init__(self, address, port):
-        self.endpoint = '{:s}:{:s}'.format(str(address), str(port))
+    def __init__(self, host=None, port=None):
+        if not host: host = get_service_host(ServiceNameEnum.DEVICE)
+        if not port: port = get_service_port_grpc(ServiceNameEnum.DEVICE)
+        self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
         LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint)))
         self.channel = None
         self.stub = None
@@ -37,41 +42,41 @@ class DeviceClient:
         self.stub = DeviceServiceStub(self.channel)
 
     def close(self):
-        if(self.channel is not None): self.channel.close()
+        if self.channel is not None: self.channel.close()
         self.channel = None
         self.stub = None
 
     @RETRY_DECORATOR
     def AddDevice(self, request : Device) -> DeviceId:
-        LOGGER.debug('AddDevice request: {:s}'.format(str(request)))
+        LOGGER.debug('AddDevice request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.AddDevice(request)
-        LOGGER.debug('AddDevice result: {:s}'.format(str(response)))
+        LOGGER.debug('AddDevice result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ConfigureDevice(self, request : Device) -> DeviceId:
-        LOGGER.debug('ConfigureDevice request: {:s}'.format(str(request)))
+        LOGGER.debug('ConfigureDevice request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ConfigureDevice(request)
-        LOGGER.debug('ConfigureDevice result: {:s}'.format(str(response)))
+        LOGGER.debug('ConfigureDevice result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def DeleteDevice(self, request : DeviceId) -> Empty:
-        LOGGER.debug('DeleteDevice request: {:s}'.format(str(request)))
+        LOGGER.debug('DeleteDevice request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.DeleteDevice(request)
-        LOGGER.debug('DeleteDevice result: {:s}'.format(str(response)))
+        LOGGER.debug('DeleteDevice result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetInitialConfig(self, request : DeviceId) -> DeviceConfig:
-        LOGGER.debug('GetInitialConfig request: {:s}'.format(str(request)))
+        LOGGER.debug('GetInitialConfig request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetInitialConfig(request)
-        LOGGER.debug('GetInitialConfig result: {:s}'.format(str(response)))
+        LOGGER.debug('GetInitialConfig result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def MonitorDeviceKpi(self, request : MonitoringSettings) -> Empty:
-        LOGGER.debug('MonitorDeviceKpi request: {:s}'.format(str(request)))
+        LOGGER.debug('MonitorDeviceKpi request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.MonitorDeviceKpi(request)
-        LOGGER.debug('MonitorDeviceKpi result: {:s}'.format(str(response)))
+        LOGGER.debug('MonitorDeviceKpi result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
diff --git a/src/device/service/DeviceService.py b/src/device/service/DeviceService.py
index bb2cc0953..4f9b032e8 100644
--- a/src/device/service/DeviceService.py
+++ b/src/device/service/DeviceService.py
@@ -12,76 +12,29 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import grpc, logging
-from concurrent import futures
-from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
-from grpc_health.v1.health_pb2 import HealthCheckResponse
-from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_port_grpc
 from common.orm.backend.BackendEnum import BackendEnum
 from common.orm.Database import Database
 from common.orm.Factory import get_database_backend
-from context.client.ContextClient import ContextClient
-from device.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+from common.tools.service.GenericGrpcService import GenericGrpcService
 from device.proto.device_pb2_grpc import add_DeviceServiceServicer_to_server
-from monitoring.client.monitoring_client import MonitoringClient
 from .driver_api.DriverInstanceCache import DriverInstanceCache
 from .DeviceServiceServicerImpl import DeviceServiceServicerImpl
 from .MonitoringLoops import MonitoringLoops
 
-BIND_ADDRESS = '0.0.0.0'
-LOGGER = logging.getLogger(__name__)
-
-class DeviceService:
-    def __init__(
-        self, context_client : ContextClient, monitoring_client : MonitoringClient,
-        driver_instance_cache : DriverInstanceCache,
-        address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD):
-
-        self.context_client = context_client
-        self.monitoring_client = monitoring_client
-        self.driver_instance_cache = driver_instance_cache
-        self.address = address
-        self.port = port
-        self.endpoint = None
-        self.max_workers = max_workers
-        self.grace_period = grace_period
-        self.device_servicer = None
-        self.health_servicer = None
-        self.pool = None
-        self.server = None
-
-        self.database = Database(get_database_backend(backend=BackendEnum.INMEMORY))
-        self.monitoring_loops = MonitoringLoops(monitoring_client, self.database)
-
-    def start(self):
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
-        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
-            str(self.endpoint), str(self.max_workers)))
+class DeviceService(GenericGrpcService):
+    def __init__(self, driver_instance_cache : DriverInstanceCache, cls_name: str = __name__) -> None:
+        port = get_service_port_grpc(ServiceNameEnum.DEVICE)
+        super().__init__(port, cls_name=cls_name)
+        database = Database(get_database_backend(backend=BackendEnum.INMEMORY))
+        self.monitoring_loops = MonitoringLoops(database)
+        self.device_servicer = DeviceServiceServicerImpl(database, driver_instance_cache, self.monitoring_loops)
 
+    def install_servicers(self):
         self.monitoring_loops.start()
-
-        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
-        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
-
-        self.device_servicer = DeviceServiceServicerImpl(
-            self.context_client, self.database, self.driver_instance_cache, self.monitoring_loops)
         add_DeviceServiceServicer_to_server(self.device_servicer, self.server)
 
-        self.health_servicer = HealthServicer(
-            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
-        add_HealthServicer_to_server(self.health_servicer, self.server)
-
-        port = self.server.add_insecure_port(self.endpoint)
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
-        LOGGER.info('Listening on {:s}...'.format(str(self.endpoint)))
-        self.server.start()
-        self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
-
-        LOGGER.debug('Service started')
-
     def stop(self):
-        LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
-        self.health_servicer.enter_graceful_shutdown()
-        self.server.stop(self.grace_period)
+        super().stop()
         self.monitoring_loops.stop()
-        LOGGER.debug('Service stopped')
diff --git a/src/device/service/DeviceServiceServicerImpl.py b/src/device/service/DeviceServiceServicerImpl.py
index 8e00b344f..e328c76cd 100644
--- a/src/device/service/DeviceServiceServicerImpl.py
+++ b/src/device/service/DeviceServiceServicerImpl.py
@@ -49,11 +49,10 @@ METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
 
 class DeviceServiceServicerImpl(DeviceServiceServicer):
     def __init__(
-        self, context_client : ContextClient, database : Database, driver_instance_cache : DriverInstanceCache,
-        monitoring_loops : MonitoringLoops):
-
+        self, database : Database, driver_instance_cache : DriverInstanceCache, monitoring_loops : MonitoringLoops
+    ) -> None:
         LOGGER.debug('Creating Servicer...')
-        self.context_client = context_client
+        self.context_client = ContextClient()
         self.database = database
         self.driver_instance_cache = driver_instance_cache
         self.monitoring_loops = monitoring_loops
diff --git a/src/device/service/MonitoringLoops.py b/src/device/service/MonitoringLoops.py
index e5b671f7f..eff634c75 100644
--- a/src/device/service/MonitoringLoops.py
+++ b/src/device/service/MonitoringLoops.py
@@ -18,7 +18,7 @@ from typing import Dict
 from common.orm.Database import Database
 from common.orm.HighLevel import get_object
 from common.orm.backend.Tools import key_to_str
-from monitoring.client.monitoring_client import MonitoringClient
+from monitoring.client.MonitoringClient import MonitoringClient
 from monitoring.proto.monitoring_pb2 import Kpi
 from .database.KpiModel import KpiModel
 from .database.RelationModels import EndPointMonitorKpiModel
@@ -55,8 +55,8 @@ class MonitoringLoop:
         self._collector_thread.join()
 
 class MonitoringLoops:
-    def __init__(self, monitoring_client : MonitoringClient, database : Database) -> None:
-        self._monitoring_client = monitoring_client
+    def __init__(self, database : Database) -> None:
+        self._monitoring_client = MonitoringClient()
         self._database = database
         self._samples_queue = queue.Queue()
         self._running = threading.Event()
@@ -82,7 +82,6 @@ class MonitoringLoops:
 
     def start(self):
         self._exporter_thread.start()
-        self._running.set()
 
     @property
     def is_running(self): return self._running.is_set()
@@ -96,6 +95,7 @@ class MonitoringLoops:
             LOGGER.error('[MonitoringLoops:_export] Database not set. Terminating Exporter.')
             return
 
+        self._running.set()
         while not self._terminate.is_set():
             try:
                 sample = self._samples_queue.get(block=True, timeout=QUEUE_GET_WAIT_TIMEOUT)
@@ -149,3 +149,5 @@ class MonitoringLoops:
                 }))
             except: # pylint: disable=bare-except
                 LOGGER.exception('Unable to format/send Kpi')
+
+        self._running.clear()
diff --git a/src/device/service/__main__.py b/src/device/service/__main__.py
index 0e92cabba..1f0adfa8f 100644
--- a/src/device/service/__main__.py
+++ b/src/device/service/__main__.py
@@ -14,12 +14,10 @@
 
 import logging, signal, sys, threading
 from prometheus_client import start_http_server
-from common.Settings import get_setting, wait_for_environment_variables
-from context.client.ContextClient import ContextClient
-from device.Config import (
-    CONTEXT_SERVICE_HOST, CONTEXT_SERVICE_PORT, GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL,
-    METRICS_PORT, MONITORING_SERVICE_HOST, MONITORING_SERVICE_PORT)
-from monitoring.client.monitoring_client import MonitoringClient
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
+    wait_for_environment_variables)
 from .DeviceService import DeviceService
 from .driver_api.DriverFactory import DriverFactory
 from .driver_api.DriverInstanceCache import DriverInstanceCache
@@ -35,12 +33,7 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
 def main():
     global LOGGER # pylint: disable=global-statement
 
-    grpc_service_port       = get_setting('DEVICESERVICE_SERVICE_PORT_GRPC',     default=GRPC_SERVICE_PORT      )
-    max_workers             = get_setting('MAX_WORKERS',                         default=GRPC_MAX_WORKERS       )
-    grace_period            = get_setting('GRACE_PERIOD',                        default=GRPC_GRACE_PERIOD      )
-    log_level               = get_setting('LOG_LEVEL',                           default=LOG_LEVEL              )
-    metrics_port            = get_setting('METRICS_PORT',                        default=METRICS_PORT           )
-
+    log_level = get_log_level()
     logging.basicConfig(level=log_level)
     logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING)
     logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING)
@@ -48,43 +41,25 @@ def main():
     LOGGER = logging.getLogger(__name__)
 
     wait_for_environment_variables([
-        'CONTEXTSERVICE_SERVICE_HOST', 'CONTEXTSERVICE_SERVICE_PORT_GRPC',
-        'MONITORINGSERVICE_SERVICE_HOST', 'MONITORINGSERVICE_SERVICE_PORT_GRPC'
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
     ])
 
-    context_service_host    = get_setting('CONTEXTSERVICE_SERVICE_HOST',         default=CONTEXT_SERVICE_HOST   )
-    context_service_port    = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC',    default=CONTEXT_SERVICE_PORT   )
-    monitoring_service_host = get_setting('MONITORINGSERVICE_SERVICE_HOST',      default=MONITORING_SERVICE_HOST)
-    monitoring_service_port = get_setting('MONITORINGSERVICE_SERVICE_PORT_GRPC', default=MONITORING_SERVICE_PORT)
-
     signal.signal(signal.SIGINT,  signal_handler)
     signal.signal(signal.SIGTERM, signal_handler)
 
     LOGGER.info('Starting...')
 
     # Start metrics server
+    metrics_port = get_metrics_port()
     start_http_server(metrics_port)
 
-    # Initialize Context Client
-    if context_service_host is None or context_service_port is None:
-        raise Exception('Wrong address({:s}):port({:s}) of Context component'.format(
-            str(context_service_host), str(context_service_port)))
-    context_client = ContextClient(context_service_host, context_service_port)
-
-    # Initialize Monitoring Client
-    if monitoring_service_host is None or monitoring_service_port is None:
-        raise Exception('Wrong address({:s}):port({:s}) of Monitoring component'.format(
-            str(monitoring_service_host), str(monitoring_service_port)))
-    monitoring_client = MonitoringClient(monitoring_service_host, monitoring_service_port)
-
     # Initialize Driver framework
     driver_factory = DriverFactory(DRIVERS)
     driver_instance_cache = DriverInstanceCache(driver_factory)
 
     # Starting device service
-    grpc_service = DeviceService(
-        context_client, monitoring_client, driver_instance_cache, port=grpc_service_port, max_workers=max_workers,
-        grace_period=grace_period)
+    grpc_service = DeviceService(driver_instance_cache)
     grpc_service.start()
 
     # Wait for Ctrl+C or termination signal
diff --git a/src/device/service/database/EndPointModel.py b/src/device/service/database/EndPointModel.py
index 286a51db6..84d0c9707 100644
--- a/src/device/service/database/EndPointModel.py
+++ b/src/device/service/database/EndPointModel.py
@@ -15,6 +15,7 @@
 import logging
 from typing import Dict, List
 from common.orm.Database import Database
+from common.orm.HighLevel import update_or_create_object
 from common.orm.backend.Tools import key_to_str
 from common.orm.fields.EnumeratedField import EnumeratedField
 from common.orm.fields.ForeignKeyField import ForeignKeyField
@@ -72,9 +73,14 @@ def set_endpoint_monitors(database : Database, db_endpoint : EndPointModel, grpc
     db_endpoint_pk = db_endpoint.pk
     for kpi_sample_type in grpc_endpoint_kpi_sample_types:
         orm_kpi_sample_type = grpc_to_enum__kpi_sample_type(kpi_sample_type)
-        str_endpoint_kpi_sample_type_key = key_to_str([db_endpoint_pk, orm_kpi_sample_type.name])
-        db_endpoint_kpi_sample_type = EndPointMonitorModel(database, str_endpoint_kpi_sample_type_key)
-        db_endpoint_kpi_sample_type.endpoint_fk = db_endpoint
-        db_endpoint_kpi_sample_type.resource_key = '' # during initialization, allow empty value
-        db_endpoint_kpi_sample_type.kpi_sample_type = orm_kpi_sample_type
-        db_endpoint_kpi_sample_type.save()
+        str_endpoint_kpi_sample_type_key = key_to_str([db_endpoint_pk, str(orm_kpi_sample_type.value)])
+        #db_endpoint_kpi_sample_type = EndPointMonitorModel(database, str_endpoint_kpi_sample_type_key)
+        #db_endpoint_kpi_sample_type.endpoint_fk = db_endpoint
+        #db_endpoint_kpi_sample_type.resource_key = '' # during initialization, allow empty value
+        #db_endpoint_kpi_sample_type.kpi_sample_type = orm_kpi_sample_type
+        #db_endpoint_kpi_sample_type.save()
+        update_or_create_object(database, EndPointMonitorModel, str_endpoint_kpi_sample_type_key, {
+            'endpoint_fk'    : db_endpoint,
+            #'resource_key'   : '', # during initialization, allow empty value
+            'kpi_sample_type': orm_kpi_sample_type,
+        })
diff --git a/src/device/service/driver_api/DriverFactory.py b/src/device/service/driver_api/DriverFactory.py
index 1e79b4ba4..b2b6c467a 100644
--- a/src/device/service/driver_api/DriverFactory.py
+++ b/src/device/service/driver_api/DriverFactory.py
@@ -76,6 +76,7 @@ class DriverFactory:
                 field_candidate_driver_classes = field_candidate_driver_classes.union(field_indice_drivers)
 
             if candidate_driver_classes is None:
+                if len(field_candidate_driver_classes) == 0: continue
                 candidate_driver_classes = {k:1 for k in field_candidate_driver_classes}
             else:
                 for candidate_driver_class in candidate_driver_classes:
diff --git a/src/device/service/drivers/__init__.py b/src/device/service/drivers/__init__.py
index 664b52821..40912f50b 100644
--- a/src/device/service/drivers/__init__.py
+++ b/src/device/service/drivers/__init__.py
@@ -23,6 +23,11 @@ from .microwave.IETFApiDriver import IETFApiDriver
 DRIVERS = [
     (EmulatedDriver, [
         {
+            # Driver==unspecified & no device type specified => use Emulated
+            FilterFieldEnum.DRIVER: ORM_DeviceDriverEnum.UNDEFINED,
+        },
+        {
+            # Emulated OLS/Packet Router, specifying Undefined/OpenConfig/TAPI Driver => use EmulatedDriver
             FilterFieldEnum.DEVICE_TYPE: [
                 DeviceTypeEnum.EMULATED_OPTICAL_LINE_SYSTEM,
                 DeviceTypeEnum.EMULATED_PACKET_ROUTER,
@@ -36,18 +41,21 @@ DRIVERS = [
     ]),
     (OpenConfigDriver, [
         {
+            # Real Packet Router, specifying OpenConfig Driver => use OpenConfigDriver
             FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.PACKET_ROUTER,
             FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.OPENCONFIG,
         }
     ]),
     (TransportApiDriver, [
         {
+            # Real OLS, specifying TAPI Driver => use TransportApiDriver
             FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.OPTICAL_LINE_SYSTEM,
             FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.TRANSPORT_API,
         }
     ]),
     (P4Driver, [
         {
+            # Real P4 Switch, specifying P4 Driver => use P4Driver
             FilterFieldEnum.DEVICE_TYPE: DeviceTypeEnum.P4_SWITCH,
             FilterFieldEnum.DRIVER     : ORM_DeviceDriverEnum.P4,
         }
diff --git a/src/device/tests/MockMonitoringService.py b/src/device/tests/MockMonitoringService.py
deleted file mode 100644
index 3e8550058..000000000
--- a/src/device/tests/MockMonitoringService.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import grpc, logging
-from concurrent import futures
-from queue import Queue
-from monitoring.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
-from monitoring.proto.monitoring_pb2_grpc import  add_MonitoringServiceServicer_to_server
-from .MockMonitoringServiceServicerImpl import MockMonitoringServiceServicerImpl
-
-BIND_ADDRESS = '0.0.0.0'
-LOGGER = logging.getLogger(__name__)
-
-class MockMonitoringService:
-    def __init__(
-        self, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS,
-        grace_period=GRPC_GRACE_PERIOD):
-
-        self.queue_samples = Queue()
-        self.address = address
-        self.port = port
-        self.endpoint = None
-        self.max_workers = max_workers
-        self.grace_period = grace_period
-        self.monitoring_servicer = None
-        self.pool = None
-        self.server = None
-
-    def start(self):
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
-        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
-            str(self.endpoint), str(self.max_workers)))
-
-        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
-        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
-
-        self.monitoring_servicer = MockMonitoringServiceServicerImpl(self.queue_samples)
-        add_MonitoringServiceServicer_to_server(self.monitoring_servicer, self.server)
-
-        port = self.server.add_insecure_port(self.endpoint)
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
-        LOGGER.info('Listening on {:s}...'.format(str(self.endpoint)))
-        self.server.start()
-
-        LOGGER.debug('Service started')
-
-    def stop(self):
-        LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
-        self.server.stop(self.grace_period)
-        LOGGER.debug('Service stopped')
diff --git a/src/device/tests/MockService_Dependencies.py b/src/device/tests/MockService_Dependencies.py
new file mode 100644
index 000000000..6b2a7788f
--- /dev/null
+++ b/src/device/tests/MockService_Dependencies.py
@@ -0,0 +1,50 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os, queue
+from typing import Union
+from common.Constants import ServiceNameEnum
+from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name
+from common.tests.MockServicerImpl_Context import MockServicerImpl_Context
+from common.tests.MockServicerImpl_Monitoring import MockServicerImpl_Monitoring
+from common.tools.service.GenericGrpcService import GenericGrpcService
+from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server
+from monitoring.proto.monitoring_pb2_grpc import add_MonitoringServiceServicer_to_server
+
+LOCAL_HOST = '127.0.0.1'
+
+SERVICE_CONTEXT = ServiceNameEnum.CONTEXT
+SERVICE_MONITORING = ServiceNameEnum.MONITORING
+
+class MockService_Dependencies(GenericGrpcService):
+    # Mock Service implementing Context and Monitoring to simplify unitary tests of Device
+
+    def __init__(self, bind_port: Union[str, int]) -> None:
+        super().__init__(bind_port, LOCAL_HOST, enable_health_servicer=False, cls_name='MockService')
+
+    # pylint: disable=attribute-defined-outside-init
+    def install_servicers(self):
+        self.context_servicer = MockServicerImpl_Context()
+        add_ContextServiceServicer_to_server(self.context_servicer, self.server)
+
+        self.queue_samples = queue.Queue()
+        self.monitoring_servicer = MockServicerImpl_Monitoring(queue_samples=self.queue_samples)
+        add_MonitoringServiceServicer_to_server(self.monitoring_servicer, self.server)
+
+    def configure_env_vars(self):
+        os.environ[get_env_var_name(SERVICE_CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     )] = str(self.bind_address)
+        os.environ[get_env_var_name(SERVICE_CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(self.bind_port)
+
+        os.environ[get_env_var_name(SERVICE_MONITORING, ENVVAR_SUFIX_SERVICE_HOST     )] = str(self.bind_address)
+        os.environ[get_env_var_name(SERVICE_MONITORING, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(self.bind_port)
diff --git a/src/device/tests/PrepareTestScenario.py b/src/device/tests/PrepareTestScenario.py
new file mode 100644
index 000000000..08991221a
--- /dev/null
+++ b/src/device/tests/PrepareTestScenario.py
@@ -0,0 +1,80 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import pytest, os
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_service_port_grpc)
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import Context, Topology
+from device.client.DeviceClient import DeviceClient
+from device.service.DeviceService import DeviceService
+from device.service.driver_api.DriverFactory import DriverFactory
+from device.service.driver_api.DriverInstanceCache import DriverInstanceCache
+from device.service.drivers import DRIVERS
+from device.tests.CommonObjects import CONTEXT, TOPOLOGY
+from device.tests.MockService_Dependencies import MockService_Dependencies
+from monitoring.client.MonitoringClient import MonitoringClient
+
+LOCAL_HOST = '127.0.0.1'
+MOCKSERVICE_PORT = 10000
+DEVICE_SERVICE_PORT = MOCKSERVICE_PORT + get_service_port_grpc(ServiceNameEnum.DEVICE) # avoid privileged ports
+os.environ[get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
+os.environ[get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(DEVICE_SERVICE_PORT)
+
+@pytest.fixture(scope='session')
+def mock_service():
+    _service = MockService_Dependencies(MOCKSERVICE_PORT)
+    _service.configure_env_vars()
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def context_client(mock_service : MockService_Dependencies): # pylint: disable=redefined-outer-name
+    _client = ContextClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def monitoring_client(mock_service : MockService_Dependencies): # pylint: disable=redefined-outer-name
+    _client = MonitoringClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def device_service(
+    context_client : ContextClient,         # pylint: disable=redefined-outer-name
+    monitoring_client : MonitoringClient):  # pylint: disable=redefined-outer-name
+
+    _driver_factory = DriverFactory(DRIVERS)
+    _driver_instance_cache = DriverInstanceCache(_driver_factory)
+    _service = DeviceService(_driver_instance_cache)
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def device_client(device_service : DeviceService): # pylint: disable=redefined-outer-name
+    _client = DeviceClient()
+    yield _client
+    _client.close()
+
+def test_prepare_environment(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    context_client.SetContext(Context(**CONTEXT))
+    context_client.SetTopology(Topology(**TOPOLOGY))
diff --git a/src/device/tests/test_unitary.py b/src/device/tests/test_unitary.py
deleted file mode 100644
index 0853da9a5..000000000
--- a/src/device/tests/test_unitary.py
+++ /dev/null
@@ -1,1010 +0,0 @@
-# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import calendar, copy, dateutil.parser, grpc, json, logging, operator, os, pytest, queue, time
-from datetime import datetime, timezone
-from typing import Tuple
-from common.orm.Database import Database
-from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
-from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
-from common.message_broker.MessageBroker import MessageBroker
-from common.tools.grpc.Tools import grpc_message_to_json_string
-from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id
-from context.Config import (
-    GRPC_SERVICE_PORT as CONTEXT_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as CONTEXT_GRPC_MAX_WORKERS,
-    GRPC_GRACE_PERIOD as CONTEXT_GRPC_GRACE_PERIOD)
-from context.client.ContextClient import ContextClient
-from context.proto.context_pb2 import DeviceId, DeviceOperationalStatusEnum
-from context.service.grpc_server.ContextService import ContextService
-from device.Config import (
-    GRPC_SERVICE_PORT as DEVICE_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as DEVICE_GRPC_MAX_WORKERS,
-    GRPC_GRACE_PERIOD as DEVICE_GRPC_GRACE_PERIOD)
-from device.client.DeviceClient import DeviceClient
-from device.proto.context_pb2 import ConfigActionEnum, Context, Device, Topology
-from device.proto.device_pb2 import MonitoringSettings
-from device.proto.kpi_sample_types_pb2 import KpiSampleType
-from device.service.DeviceService import DeviceService
-from device.service.driver_api._Driver import _Driver
-from device.service.driver_api.DriverFactory import DriverFactory
-from device.service.driver_api.DriverInstanceCache import DriverInstanceCache
-from device.service.drivers import DRIVERS
-from device.tests.MockMonitoringService import MockMonitoringService
-from monitoring.Config import (
-    GRPC_SERVICE_PORT as MONITORING_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as MONITORING_GRPC_MAX_WORKERS,
-    GRPC_GRACE_PERIOD as MONITORING_GRPC_GRACE_PERIOD)
-from monitoring.client.monitoring_client import MonitoringClient
-from .CommonObjects import CONTEXT, TOPOLOGY
-
-from .Device_Emulated import (
-    DEVICE_EMU, DEVICE_EMU_CONFIG_ADDRESSES, DEVICE_EMU_CONFIG_ENDPOINTS, DEVICE_EMU_CONNECT_RULES,
-    DEVICE_EMU_DECONFIG_ADDRESSES, DEVICE_EMU_DECONFIG_ENDPOINTS, DEVICE_EMU_EP_DESCS, DEVICE_EMU_ENDPOINTS_COOKED,
-    DEVICE_EMU_ID, DEVICE_EMU_RECONFIG_ADDRESSES, DEVICE_EMU_UUID)
-ENABLE_EMULATED = True
-
-try:
-    from .Device_OpenConfig_Infinera1 import(
-    #from .Device_OpenConfig_Infinera2 import(
-    #from .Device_OpenConfig_Cisco import(
-    #from .Device_OpenConfig_Adva import(
-
-        DEVICE_OC, DEVICE_OC_CONFIG_RULES, DEVICE_OC_DECONFIG_RULES, DEVICE_OC_CONNECT_RULES, DEVICE_OC_ID,
-        DEVICE_OC_UUID)
-    ENABLE_OPENCONFIG = True
-except ImportError:
-    ENABLE_OPENCONFIG = False
-
-try:
-    from .Device_Transport_Api_CTTC import (
-        DEVICE_TAPI, DEVICE_TAPI_CONNECT_RULES, DEVICE_TAPI_UUID, DEVICE_TAPI_ID, DEVICE_TAPI_CONFIG_RULES,
-        DEVICE_TAPI_DECONFIG_RULES)
-    ENABLE_TAPI = True
-except ImportError:
-    ENABLE_TAPI = False
-
-from .mock_p4runtime_service import MockP4RuntimeService
-try:
-    from .device_p4 import(
-        DEVICE_P4, DEVICE_P4_ID, DEVICE_P4_UUID, DEVICE_P4_NAME, DEVICE_P4_ADDRESS, DEVICE_P4_PORT, DEVICE_P4_WORKERS,
-        DEVICE_P4_GRACE_PERIOD, DEVICE_P4_CONNECT_RULES, DEVICE_P4_CONFIG_RULES)
-    ENABLE_P4 = True
-except ImportError:
-    ENABLE_P4 = False
-
-#ENABLE_EMULATED   = False # set to False to disable tests of Emulated devices
-#ENABLE_OPENCONFIG = False # set to False to disable tests of OpenConfig devices
-#ENABLE_TAPI       = False # set to False to disable tests of TAPI devices
-#ENABLE_P4         = False # set to False to disable tests of P4 devices
-
-ENABLE_OPENCONFIG_CONFIGURE   = True
-ENABLE_OPENCONFIG_MONITOR     = True
-ENABLE_OPENCONFIG_DECONFIGURE = True
-
-
-logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING)
-logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING)
-logging.getLogger('monitoring-client').setLevel(logging.WARNING)
-
-LOGGER = logging.getLogger(__name__)
-LOGGER.setLevel(logging.DEBUG)
-
-CONTEXT_GRPC_SERVICE_PORT = 10000 + CONTEXT_GRPC_SERVICE_PORT # avoid privileged ports
-DEVICE_GRPC_SERVICE_PORT = 10000 + DEVICE_GRPC_SERVICE_PORT # avoid privileged ports
-MONITORING_GRPC_SERVICE_PORT = 10000 + MONITORING_GRPC_SERVICE_PORT # avoid privileged ports
-
-DEFAULT_REDIS_SERVICE_HOST = '127.0.0.1'
-DEFAULT_REDIS_SERVICE_PORT = 6379
-DEFAULT_REDIS_DATABASE_ID  = 0
-
-REDIS_CONFIG = {
-    'REDIS_SERVICE_HOST': os.environ.get('REDIS_SERVICE_HOST', DEFAULT_REDIS_SERVICE_HOST),
-    'REDIS_SERVICE_PORT': os.environ.get('REDIS_SERVICE_PORT', DEFAULT_REDIS_SERVICE_PORT),
-    'REDIS_DATABASE_ID' : os.environ.get('REDIS_DATABASE_ID',  DEFAULT_REDIS_DATABASE_ID ),
-}
-
-SCENARIOS = [
-    ('all_inmemory', DatabaseBackendEnum.INMEMORY, {},           MessageBrokerBackendEnum.INMEMORY, {}          ),
-    #('all_redis',    DatabaseBackendEnum.REDIS,    REDIS_CONFIG, MessageBrokerBackendEnum.REDIS,    REDIS_CONFIG),
-]
-
-@pytest.fixture(scope='session', ids=[str(scenario[0]) for scenario in SCENARIOS], params=SCENARIOS)
-def context_db_mb(request) -> Tuple[Database, MessageBroker]:
-    name,db_backend,db_settings,mb_backend,mb_settings = request.param
-    msg = 'Running scenario {:s} db_backend={:s}, db_settings={:s}, mb_backend={:s}, mb_settings={:s}...'
-    LOGGER.info(msg.format(str(name), str(db_backend.value), str(db_settings), str(mb_backend.value), str(mb_settings)))
-    _database = Database(get_database_backend(backend=db_backend, **db_settings))
-    _message_broker = MessageBroker(get_messagebroker_backend(backend=mb_backend, **mb_settings))
-    yield _database, _message_broker
-    _message_broker.terminate()
-
-@pytest.fixture(scope='session')
-def context_service(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
-    _service = ContextService(
-        context_db_mb[0], context_db_mb[1], port=CONTEXT_GRPC_SERVICE_PORT, max_workers=CONTEXT_GRPC_MAX_WORKERS,
-        grace_period=CONTEXT_GRPC_GRACE_PERIOD)
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def context_client(context_service : ContextService): # pylint: disable=redefined-outer-name
-    _client = ContextClient(address='127.0.0.1', port=CONTEXT_GRPC_SERVICE_PORT)
-    yield _client
-    _client.close()
-
-@pytest.fixture(scope='session')
-def monitoring_service():
-    _service = MockMonitoringService(port=MONITORING_GRPC_SERVICE_PORT, max_workers=MONITORING_GRPC_MAX_WORKERS,
-        grace_period=MONITORING_GRPC_GRACE_PERIOD)
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def monitoring_client(monitoring_service : MockMonitoringService): # pylint: disable=redefined-outer-name
-    _client = MonitoringClient(server='127.0.0.1', port=MONITORING_GRPC_SERVICE_PORT)
-    #yield _client
-    #_client.close()
-    return _client
-
-@pytest.fixture(scope='session')
-def device_service(
-    context_client : ContextClient,         # pylint: disable=redefined-outer-name
-    monitoring_client : MonitoringClient):  # pylint: disable=redefined-outer-name
-
-    _driver_factory = DriverFactory(DRIVERS)
-    _driver_instance_cache = DriverInstanceCache(_driver_factory)
-    _service = DeviceService(
-        context_client, monitoring_client, _driver_instance_cache, port=DEVICE_GRPC_SERVICE_PORT,
-        max_workers=DEVICE_GRPC_MAX_WORKERS, grace_period=DEVICE_GRPC_GRACE_PERIOD)
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def device_client(device_service : DeviceService): # pylint: disable=redefined-outer-name
-    _client = DeviceClient(address='127.0.0.1', port=DEVICE_GRPC_SERVICE_PORT)
-    yield _client
-    _client.close()
-
-@pytest.fixture(scope='session')
-def p4runtime_service():
-    _service = MockP4RuntimeService(
-        address=DEVICE_P4_ADDRESS, port=DEVICE_P4_PORT,
-        max_workers=DEVICE_P4_WORKERS,
-        grace_period=DEVICE_P4_GRACE_PERIOD)
-    _service.start()
-    yield _service
-    _service.stop()
-
-
-def test_prepare_environment(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    context_client.SetContext(Context(**CONTEXT))
-    context_client.SetTopology(Topology(**TOPOLOGY))
-
-
-# ----- Test Device Driver Emulated --------------------------------------------
-# Device Driver Emulated tests are used to validate Driver API as well as Emulated Device Driver. Note that other
-# Drivers might support a different set of resource paths, and attributes/values per resource; however, they must
-# implement the Driver API.
-
-def test_device_emulated_add_error_cases(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_EMULATED: pytest.skip('Skipping test: No Emulated device has been configured')
-
-    with pytest.raises(grpc.RpcError) as e:
-        DEVICE_EMU_WITH_ENDPOINTS = copy.deepcopy(DEVICE_EMU)
-        DEVICE_EMU_WITH_ENDPOINTS['device_endpoints'].append(json_endpoint(DEVICE_EMU_ID, 'ep-id', 'ep-type'))
-        device_client.AddDevice(Device(**DEVICE_EMU_WITH_ENDPOINTS))
-    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
-    msg_head = 'device.device_endpoints(['
-    msg_tail = ']) is invalid; RPC method AddDevice does not accept Endpoints. '\
-               'Endpoints are discovered through interrogation of the physical device.'
-    except_msg = str(e.value.details())
-    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
-
-    with pytest.raises(grpc.RpcError) as e:
-        DEVICE_EMU_WITH_EXTRA_RULES = copy.deepcopy(DEVICE_EMU)
-        DEVICE_EMU_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONNECT_RULES)
-        DEVICE_EMU_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONFIG_ENDPOINTS)
-        device_client.AddDevice(Device(**DEVICE_EMU_WITH_EXTRA_RULES))
-    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
-    msg_head = 'device.device_config.config_rules(['
-    msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\
-               'with "_connect/" tag. Others should be configured after adding the device.'
-    except_msg = str(e.value.details())
-    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
-
-
-def test_device_emulated_add_correct(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_EMULATED: pytest.skip('Skipping test: No Emulated device has been configured')
-
-    DEVICE_EMU_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_EMU)
-    DEVICE_EMU_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONNECT_RULES)
-    device_client.AddDevice(Device(**DEVICE_EMU_WITH_CONNECT_RULES))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_EMU_UUID) # we know the driver exists now
-    assert driver is not None
-
-
-def test_device_emulated_get(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_EMULATED: pytest.skip('Skipping test: No Emulated device has been configured')
-
-    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_EMU_ID))
-    LOGGER.info('initial_config = {:s}'.format(grpc_message_to_json_string(initial_config)))
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID))
-    LOGGER.info('device_data = {:s}'.format(grpc_message_to_json_string(device_data)))
-
-
-def test_device_emulated_configure(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_EMULATED: pytest.skip('Skipping test: No Emulated device has been configured')
-
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_EMU_UUID) # we know the driver exists now
-    assert driver is not None
-
-    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-    assert len(driver_config) == len(DEVICE_EMU_ENDPOINTS_COOKED)
-    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
-        assert endpoint_cooked in driver_config
-
-    DEVICE_EMU_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_EMU)
-    DEVICE_EMU_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONFIG_ENDPOINTS)
-    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_CONFIG_RULES))
-
-    DEVICE_EMU_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_EMU)
-    DEVICE_EMU_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONFIG_ADDRESSES)
-    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_CONFIG_RULES))
-
-    DEVICE_EMU_WITH_OPERATIONAL_STATUS = copy.deepcopy(DEVICE_EMU)
-    DEVICE_EMU_WITH_OPERATIONAL_STATUS['device_operational_status'] = \
-        DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
-    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_OPERATIONAL_STATUS))
-
-    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-    assert len(driver_config) == len(DEVICE_EMU_ENDPOINTS_COOKED) + len(DEVICE_EMU_CONFIG_ADDRESSES)
-    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
-        endpoint_cooked = copy.deepcopy(endpoint_cooked)
-        endpoint_cooked[1]['enabled'] = True
-        assert endpoint_cooked in driver_config
-    for config_rule in DEVICE_EMU_CONFIG_ADDRESSES:
-        assert (config_rule['resource_key'], json.loads(config_rule['resource_value'])) in driver_config
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID))
-    assert device_data.device_operational_status == DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
-
-    config_rules = [
-        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
-        for config_rule in device_data.device_config.config_rules
-    ]
-    #LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
-    #    '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
-    RESULTING_CONFIG_ENDPOINTS = {cr['resource_key']:cr for cr in copy.deepcopy(DEVICE_EMU_CONFIG_ENDPOINTS)}
-    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
-        values = json.loads(RESULTING_CONFIG_ENDPOINTS[endpoint_cooked[0]]['resource_value'])
-        values.update(endpoint_cooked[1])
-        RESULTING_CONFIG_ENDPOINTS[endpoint_cooked[0]]['resource_value'] = json.dumps(values, sort_keys=True)
-    for config_rule in RESULTING_CONFIG_ENDPOINTS.values():
-        config_rule = (
-            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'],
-            json.loads(json.dumps(config_rule['resource_value'])))
-        assert config_rule in config_rules
-    for config_rule in DEVICE_EMU_CONFIG_ADDRESSES:
-        config_rule = (
-            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'],
-            json.loads(json.dumps(config_rule['resource_value'])))
-        assert config_rule in config_rules
-
-    # Try to reconfigure...
-
-    DEVICE_EMU_WITH_RECONFIG_RULES = copy.deepcopy(DEVICE_EMU)
-    DEVICE_EMU_WITH_RECONFIG_RULES['device_operational_status'] = \
-        DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
-    DEVICE_EMU_WITH_RECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_RECONFIG_ADDRESSES)
-    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_RECONFIG_RULES))
-
-    RESULTING_CONFIG_RULES = {cr['resource_key']:cr for cr in copy.deepcopy(DEVICE_EMU_CONFIG_ENDPOINTS)}
-    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
-        values = json.loads(RESULTING_CONFIG_RULES[endpoint_cooked[0]]['resource_value'])
-        values.update(endpoint_cooked[1])
-        RESULTING_CONFIG_RULES[endpoint_cooked[0]]['resource_value'] = json.dumps(values, sort_keys=True)
-    RESULTING_CONFIG_RULES.update({cr['resource_key']:cr for cr in copy.deepcopy(DEVICE_EMU_CONFIG_ADDRESSES)})
-    for reconfig_rule in DEVICE_EMU_RECONFIG_ADDRESSES:
-        if reconfig_rule['action'] == ConfigActionEnum.CONFIGACTION_DELETE:
-            RESULTING_CONFIG_RULES.pop(reconfig_rule['resource_key'], None)
-        else:
-            RESULTING_CONFIG_RULES[reconfig_rule['resource_key']] = reconfig_rule
-    RESULTING_CONFIG_RULES = RESULTING_CONFIG_RULES.values()
-    #LOGGER.info('RESULTING_CONFIG_RULES = {:s}'.format(str(RESULTING_CONFIG_RULES)))
-
-    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    driver_config = json.loads(json.dumps(driver_config)) # prevent integer keys to fail matching with string keys
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-    assert len(driver_config) == len(RESULTING_CONFIG_RULES)
-    for config_rule in RESULTING_CONFIG_RULES:
-        resource = [config_rule['resource_key'], json.loads(config_rule['resource_value'])]
-        assert resource in driver_config
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID))
-    config_rules = [
-        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
-        for config_rule in device_data.device_config.config_rules
-    ]
-    #LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
-    #    '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
-    for config_rule in RESULTING_CONFIG_RULES:
-        config_rule = (
-            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value'])
-        assert config_rule in config_rules
-
-
-def test_device_emulated_monitor(
-    context_client : ContextClient,                 # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,                   # pylint: disable=redefined-outer-name
-    device_service : DeviceService,                 # pylint: disable=redefined-outer-name
-    monitoring_service : MockMonitoringService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_EMULATED: pytest.skip('Skipping test: No Emulated device has been configured')
-
-    device_uuid = DEVICE_EMU_UUID
-    json_device_id = DEVICE_EMU_ID
-    device_id = DeviceId(**json_device_id)
-    device_data = context_client.GetDevice(device_id)
-    #LOGGER.info('device_data = \n{:s}'.format(str(device_data)))
-
-    driver : _Driver = device_service.driver_instance_cache.get(device_uuid) # we know the driver exists now
-    assert driver is not None
-    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-    #assert len(driver_config) == len(DEVICE_EMU_ENDPOINTS_COOKED) + len(DEVICE_EMU_CONFIG_ADDRESSES)
-
-    SAMPLING_DURATION_SEC = 10.0
-    SAMPLING_INTERVAL_SEC = 2.0
-
-    MONITORING_SETTINGS_LIST = []
-    KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {}
-    for endpoint in device_data.device_endpoints:
-        endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
-        for sample_type_id in endpoint.kpi_sample_types:
-            sample_type_name = str(KpiSampleType.Name(sample_type_id)).upper().replace('KPISAMPLETYPE_', '')
-            kpi_uuid = '{:s}-{:s}-{:s}-kpi_uuid'.format(device_uuid, endpoint_uuid, str(sample_type_id))
-            monitoring_settings = {
-                'kpi_id'        : {'kpi_id': {'uuid': kpi_uuid}},
-                'kpi_descriptor': {
-                    'kpi_description': 'Metric {:s} for Endpoint {:s} in Device {:s}'.format(
-                        sample_type_name, endpoint_uuid, device_uuid),
-                    'kpi_sample_type': sample_type_id,
-                    'device_id': json_device_id,
-                    'endpoint_id': json_endpoint_id(json_device_id, endpoint_uuid),
-                },
-                'sampling_duration_s': SAMPLING_DURATION_SEC,
-                'sampling_interval_s': SAMPLING_INTERVAL_SEC,
-            }
-            MONITORING_SETTINGS_LIST.append(monitoring_settings)
-            KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] = 0
-
-    NUM_SAMPLES_EXPECTED_PER_KPI = SAMPLING_DURATION_SEC / SAMPLING_INTERVAL_SEC
-    NUM_SAMPLES_EXPECTED = len(MONITORING_SETTINGS_LIST) * NUM_SAMPLES_EXPECTED_PER_KPI
-
-    # Start monitoring the device
-    t_start_monitoring = datetime.timestamp(datetime.utcnow())
-    for monitoring_settings in MONITORING_SETTINGS_LIST:
-        device_client.MonitorDeviceKpi(MonitoringSettings(**monitoring_settings))
-
-    # wait to receive the expected number of samples
-    # if takes more than 1.5 times the sampling duration, assume there is an error
-    time_ini = time.time()
-    queue_samples : queue.Queue = monitoring_service.queue_samples
-    received_samples = []
-    while (len(received_samples) < NUM_SAMPLES_EXPECTED) and (time.time() - time_ini < SAMPLING_DURATION_SEC * 1.5):
-        try:
-            received_sample = queue_samples.get(block=True, timeout=SAMPLING_INTERVAL_SEC / NUM_SAMPLES_EXPECTED)
-            #LOGGER.info('received_sample = {:s}'.format(str(received_sample)))
-            received_samples.append(received_sample)
-        except queue.Empty:
-            continue
-
-    t_end_monitoring = datetime.timestamp(datetime.utcnow())
-
-    #LOGGER.info('received_samples = {:s}'.format(str(received_samples)))
-    LOGGER.info('len(received_samples) = {:s}'.format(str(len(received_samples))))
-    LOGGER.info('NUM_SAMPLES_EXPECTED = {:s}'.format(str(NUM_SAMPLES_EXPECTED)))
-    assert len(received_samples) == NUM_SAMPLES_EXPECTED
-    for received_sample in received_samples:
-        kpi_uuid = received_sample.kpi_id.kpi_id.uuid
-        assert kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED
-        assert isinstance(received_sample.timestamp, str)
-        try:
-            timestamp = float(received_sample.timestamp)
-        except ValueError:
-            dt_time = dateutil.parser.isoparse(received_sample.timestamp).replace(tzinfo=timezone.utc)
-            timestamp = float(calendar.timegm(dt_time.timetuple())) + (dt_time.microsecond / 1.e6)
-        assert timestamp > t_start_monitoring
-        assert timestamp < t_end_monitoring
-        assert received_sample.kpi_value.HasField('floatVal') or received_sample.kpi_value.HasField('intVal')
-        kpi_value = getattr(received_sample.kpi_value, received_sample.kpi_value.WhichOneof('value'))
-        assert isinstance(kpi_value, (float, int))
-        KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] += 1
-
-    LOGGER.info('KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {:s}'.format(str(KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED)))
-    for kpi_uuid, num_samples_received in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED.items():
-        assert num_samples_received == NUM_SAMPLES_EXPECTED_PER_KPI
-
-    # Unsubscribe monitoring
-    for kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED.keys():
-        MONITORING_SETTINGS_UNSUBSCRIBE = {
-            'kpi_id'             : {'kpi_id': {'uuid': kpi_uuid}},
-            'sampling_duration_s': -1, # negative value in sampling_duration_s or sampling_interval_s means unsibscribe
-            'sampling_interval_s': -1, # kpi_id is mandatory to unsibscribe
-        }
-        device_client.MonitorDeviceKpi(MonitoringSettings(**MONITORING_SETTINGS_UNSUBSCRIBE))
-
-
-def test_device_emulated_deconfigure(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_EMULATED: pytest.skip('Skipping test: No Emulated device has been configured')
-
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_EMU_UUID) # we know the driver exists now
-    assert driver is not None
-
-    driver_config = driver.GetConfig()
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-
-    DEVICE_EMU_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_EMU)
-    DEVICE_EMU_WITH_DECONFIG_RULES['device_operational_status'] = \
-        DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED
-    DEVICE_EMU_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_DECONFIG_ADDRESSES)
-    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_DECONFIG_RULES))
-
-    RESULTING_CONFIG_RULES = {cr['resource_key']:cr for cr in copy.deepcopy(DEVICE_EMU_CONFIG_ENDPOINTS)}
-    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
-        values = json.loads(RESULTING_CONFIG_RULES[endpoint_cooked[0]]['resource_value'])
-        values.update(endpoint_cooked[1])
-        RESULTING_CONFIG_RULES[endpoint_cooked[0]]['resource_value'] = json.dumps(values, sort_keys=True)
-    RESULTING_CONFIG_RULES = RESULTING_CONFIG_RULES.values()
-    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    driver_config = json.loads(json.dumps(driver_config)) # prevent integer keys to fail matching with string keys
-    driver_config = list(filter(
-        lambda config_rule: (
-            not isinstance(config_rule[1], str) or not config_rule[1].startswith('do_sampling (trigger:')),
-        driver_config))
-    LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-    LOGGER.info('RESULTING_CONFIG_RULES = {:s}'.format(str(RESULTING_CONFIG_RULES)))
-    assert len(driver_config) == len(RESULTING_CONFIG_RULES)
-    for config_rule in RESULTING_CONFIG_RULES:
-        config_rule = [config_rule['resource_key'], json.loads(config_rule['resource_value'])]
-        #LOGGER.info('config_rule = {:s}'.format(str(config_rule)))
-        assert config_rule in driver_config
-
-    DEVICE_EMU_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_EMU)
-    DEVICE_EMU_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_DECONFIG_ENDPOINTS)
-    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_DECONFIG_RULES))
-
-    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    driver_config = json.loads(json.dumps(driver_config)) # prevent integer keys to fail matching with string keys
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-    assert len(driver_config) == 0
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID))
-    config_rules = device_data.device_config.config_rules
-    LOGGER.info('config_rules = {:s}'.format(str(config_rules)))
-    clean_config_rules = []
-    for config_rule in config_rules:
-        config_rule_value = json.loads(config_rule.resource_value)
-        if not isinstance(config_rule_value, str): clean_config_rules.append(config_rule)
-        if config_rule_value.startswith('do_sampling (trigger:'): continue
-        clean_config_rules.append(config_rule)
-    LOGGER.info('clean_config_rules = {:s}'.format(str(clean_config_rules)))
-    assert len(clean_config_rules) == 0
-
-
-def test_device_emulated_delete(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_EMULATED: pytest.skip('Skipping test: No Emulated device has been configured')
-
-    device_client.DeleteDevice(DeviceId(**DEVICE_EMU_ID))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_EMU_UUID, {})
-    assert driver is None
-
-
-# ----- Test Device Driver OpenConfig ------------------------------------------
-
-def test_device_openconfig_add_error_cases(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
-
-    with pytest.raises(grpc.RpcError) as e:
-        DEVICE_OC_WITH_EXTRA_RULES = copy.deepcopy(DEVICE_OC)
-        DEVICE_OC_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONNECT_RULES)
-        DEVICE_OC_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONFIG_RULES)
-        device_client.AddDevice(Device(**DEVICE_OC_WITH_EXTRA_RULES))
-    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
-    msg_head = 'device.device_config.config_rules(['
-    msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\
-               'with "_connect/" tag. Others should be configured after adding the device.'
-    except_msg = str(e.value.details())
-    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
-
-
-def test_device_openconfig_add_correct(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
-
-    DEVICE_OC_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_OC)
-    DEVICE_OC_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONNECT_RULES)
-    device_client.AddDevice(Device(**DEVICE_OC_WITH_CONNECT_RULES))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now
-    assert driver is not None
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID))
-    config_rules = [
-        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
-        for config_rule in device_data.device_config.config_rules
-    ]
-    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
-        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
-
-
-def test_device_openconfig_get(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
-
-    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_OC_ID))
-    LOGGER.info('initial_config = {:s}'.format(grpc_message_to_json_string(initial_config)))
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID))
-    LOGGER.info('device_data = {:s}'.format(grpc_message_to_json_string(device_data)))
-
-
-def test_device_openconfig_configure(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
-    if not ENABLE_OPENCONFIG_CONFIGURE: pytest.skip('Skipping test OpenConfig configure')
-
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now
-    assert driver is not None
-
-    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
-    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-
-    DEVICE_OC_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_OC)
-    DEVICE_OC_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONFIG_RULES)
-    device_client.ConfigureDevice(Device(**DEVICE_OC_WITH_CONFIG_RULES))
-
-    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
-    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID))
-    config_rules = [
-        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
-        for config_rule in device_data.device_config.config_rules
-    ]
-    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
-        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
-    for config_rule in DEVICE_OC_CONFIG_RULES:
-        config_rule = (
-            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value'])
-        assert config_rule in config_rules
-
-
-def test_device_openconfig_monitor(
-    context_client : ContextClient,                 # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,                   # pylint: disable=redefined-outer-name
-    device_service : DeviceService,                 # pylint: disable=redefined-outer-name
-    monitoring_service : MockMonitoringService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
-    if not ENABLE_OPENCONFIG_MONITOR: pytest.skip('Skipping test OpenConfig monitor')
-
-    device_uuid = DEVICE_OC_UUID
-    json_device_id = DEVICE_OC_ID
-    device_id = DeviceId(**json_device_id)
-    device_data = context_client.GetDevice(device_id)
-    #LOGGER.info('device_data = \n{:s}'.format(str(device_data)))
-
-    driver : _Driver = device_service.driver_instance_cache.get(device_uuid) # we know the driver exists now
-    assert driver is not None
-
-    SAMPLING_DURATION_SEC = 60.0
-    SAMPLING_INTERVAL_SEC = 15.0
-
-    MONITORING_SETTINGS_LIST = []
-    KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {}
-    for endpoint in device_data.device_endpoints:
-        endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
-        for sample_type_id in endpoint.kpi_sample_types:
-            sample_type_name = str(KpiSampleType.Name(sample_type_id)).upper().replace('KPISAMPLETYPE_', '')
-            kpi_uuid = '{:s}-{:s}-{:s}-kpi_uuid'.format(device_uuid, endpoint_uuid, str(sample_type_id))
-            monitoring_settings = {
-                'kpi_id'        : {'kpi_id': {'uuid': kpi_uuid}},
-                'kpi_descriptor': {
-                    'kpi_description': 'Metric {:s} for Endpoint {:s} in Device {:s}'.format(
-                        sample_type_name, endpoint_uuid, device_uuid),
-                    'kpi_sample_type': sample_type_id,
-                    'device_id': json_device_id,
-                    'endpoint_id': json_endpoint_id(json_device_id, endpoint_uuid),
-                },
-                'sampling_duration_s': SAMPLING_DURATION_SEC,
-                'sampling_interval_s': SAMPLING_INTERVAL_SEC,
-            }
-            MONITORING_SETTINGS_LIST.append(monitoring_settings)
-            KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] = 0
-
-    NUM_SAMPLES_EXPECTED_PER_KPI = SAMPLING_DURATION_SEC / SAMPLING_INTERVAL_SEC
-    NUM_SAMPLES_EXPECTED = len(MONITORING_SETTINGS_LIST) * NUM_SAMPLES_EXPECTED_PER_KPI
-
-    # Start monitoring the device
-    t_start_monitoring = datetime.timestamp(datetime.utcnow())
-    for monitoring_settings in MONITORING_SETTINGS_LIST:
-        device_client.MonitorDeviceKpi(MonitoringSettings(**monitoring_settings))
-
-    # wait to receive the expected number of samples
-    # if takes more than 1.5 times the sampling duration, assume there is an error
-    time_ini = time.time()
-    queue_samples : queue.Queue = monitoring_service.queue_samples
-    received_samples = []
-    while (len(received_samples) < NUM_SAMPLES_EXPECTED) and (time.time() - time_ini < SAMPLING_DURATION_SEC * 1.5):
-        try:
-            received_sample = queue_samples.get(block=True, timeout=SAMPLING_INTERVAL_SEC / NUM_SAMPLES_EXPECTED)
-            #LOGGER.info('received_sample = {:s}'.format(str(received_sample)))
-            received_samples.append(received_sample)
-        except queue.Empty:
-            continue
-
-    t_end_monitoring = datetime.timestamp(datetime.utcnow())
-
-    #LOGGER.info('received_samples = {:s}'.format(str(received_samples)))
-    LOGGER.info('len(received_samples) = {:s}'.format(str(len(received_samples))))
-    LOGGER.info('NUM_SAMPLES_EXPECTED = {:s}'.format(str(NUM_SAMPLES_EXPECTED)))
-    #assert len(received_samples) == NUM_SAMPLES_EXPECTED
-    for received_sample in received_samples:
-        kpi_uuid = received_sample.kpi_id.kpi_id.uuid
-        assert kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED
-        assert isinstance(received_sample.timestamp, str)
-        try:
-            timestamp = float(received_sample.timestamp)
-        except ValueError:
-            dt_time = dateutil.parser.isoparse(received_sample.timestamp).replace(tzinfo=timezone.utc)
-            timestamp = float(calendar.timegm(dt_time.timetuple())) + (dt_time.microsecond / 1.e6)
-        assert timestamp > t_start_monitoring
-        assert timestamp < t_end_monitoring
-        assert received_sample.kpi_value.HasField('floatVal') or received_sample.kpi_value.HasField('intVal')
-        kpi_value = getattr(received_sample.kpi_value, received_sample.kpi_value.WhichOneof('value'))
-        assert isinstance(kpi_value, (float, int))
-        KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] += 1
-
-    LOGGER.info('KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {:s}'.format(str(KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED)))
-    # TODO: review why num_samples_received per KPI != NUM_SAMPLES_EXPECTED_PER_KPI
-    #for kpi_uuid, num_samples_received in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED.items():
-    #    assert num_samples_received == NUM_SAMPLES_EXPECTED_PER_KPI
-
-    # Unsubscribe monitoring
-    for kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED.keys():
-        MONITORING_SETTINGS_UNSUBSCRIBE = {
-            'kpi_id'             : {'kpi_id': {'uuid': kpi_uuid}},
-            'sampling_duration_s': -1, # negative value in sampling_duration_s or sampling_interval_s means unsibscribe
-            'sampling_interval_s': -1, # kpi_id is mandatory to unsibscribe
-        }
-        device_client.MonitorDeviceKpi(MonitoringSettings(**MONITORING_SETTINGS_UNSUBSCRIBE))
-
-
-def test_device_openconfig_deconfigure(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
-    if not ENABLE_OPENCONFIG_DECONFIGURE: pytest.skip('Skipping test OpenConfig deconfigure')
-
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now
-    assert driver is not None
-
-    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
-    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-
-    DEVICE_OC_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_OC)
-    DEVICE_OC_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_OC_DECONFIG_RULES)
-    device_client.ConfigureDevice(Device(**DEVICE_OC_WITH_DECONFIG_RULES))
-
-    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
-    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID))
-    config_rules = [
-        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
-        for config_rule in device_data.device_config.config_rules
-    ]
-    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
-        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
-    for config_rule in DEVICE_OC_DECONFIG_RULES:
-        action_set = ConfigActionEnum.Name(ConfigActionEnum.CONFIGACTION_SET)
-        config_rule = (action_set, config_rule['resource_key'], config_rule['resource_value'])
-        assert config_rule not in config_rules
-
-
-def test_device_openconfig_delete(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
-
-    device_client.DeleteDevice(DeviceId(**DEVICE_OC_ID))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_OC_UUID, {})
-    assert driver is None
-
-
-# ----- Test Device Driver TAPI ------------------------------------------------
-
-def test_device_tapi_add_error_cases(
-    device_client : DeviceClient):      # pylint: disable=redefined-outer-name
-
-    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
-
-    with pytest.raises(grpc.RpcError) as e:
-        DEVICE_TAPI_WITH_EXTRA_RULES = copy.deepcopy(DEVICE_TAPI)
-        DEVICE_TAPI_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_CONNECT_RULES)
-        DEVICE_TAPI_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_CONFIG_RULES)
-        device_client.AddDevice(Device(**DEVICE_TAPI_WITH_EXTRA_RULES))
-    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
-    msg_head = 'device.device_config.config_rules(['
-    msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\
-               'with "_connect/" tag. Others should be configured after adding the device.'
-    except_msg = str(e.value.details())
-    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
-
-
-def test_device_tapi_add_correct(
-    device_client: DeviceClient,        # pylint: disable=redefined-outer-name
-    device_service: DeviceService):     # pylint: disable=redefined-outer-name
-
-    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
-
-    DEVICE_TAPI_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_TAPI)
-    DEVICE_TAPI_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_CONNECT_RULES)
-    device_client.AddDevice(Device(**DEVICE_TAPI_WITH_CONNECT_RULES))
-    driver: _Driver = device_service.driver_instance_cache.get(DEVICE_TAPI_UUID)
-    assert driver is not None
-
-
-def test_device_tapi_get(
-    context_client: ContextClient,      # pylint: disable=redefined-outer-name
-    device_client: DeviceClient):       # pylint: disable=redefined-outer-name
-
-    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
-
-    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_TAPI_ID))
-    LOGGER.info('initial_config = {:s}'.format(grpc_message_to_json_string(initial_config)))
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_TAPI_ID))
-    LOGGER.info('device_data = {:s}'.format(grpc_message_to_json_string(device_data)))
-
-
-def test_device_tapi_configure(
-    context_client: ContextClient,      # pylint: disable=redefined-outer-name
-    device_client: DeviceClient,        # pylint: disable=redefined-outer-name
-    device_service: DeviceService):     # pylint: disable=redefined-outer-name
-
-    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
-
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_TAPI_UUID)
-    assert driver is not None
-
-    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
-    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-
-    DEVICE_TAPI_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_TAPI)
-    DEVICE_TAPI_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_CONFIG_RULES)
-    device_client.ConfigureDevice(Device(**DEVICE_TAPI_WITH_CONFIG_RULES))
-
-    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
-    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_TAPI_ID))
-    config_rules = [
-        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
-        for config_rule in device_data.device_config.config_rules
-    ]
-    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
-        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
-    for config_rule in DEVICE_TAPI_CONFIG_RULES:
-        config_rule = (
-            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value'])
-        assert config_rule in config_rules
-
-
-def test_device_tapi_deconfigure(
-    context_client: ContextClient,      # pylint: disable=redefined-outer-name
-    device_client: DeviceClient,        # pylint: disable=redefined-outer-name
-    device_service: DeviceService):     # pylint: disable=redefined-outer-name
-
-    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
-
-    driver: _Driver = device_service.driver_instance_cache.get(DEVICE_TAPI_UUID)
-    assert driver is not None
-
-    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
-    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-
-    DEVICE_TAPI_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_TAPI)
-    DEVICE_TAPI_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_DECONFIG_RULES)
-    device_client.ConfigureDevice(Device(**DEVICE_TAPI_WITH_DECONFIG_RULES))
-
-    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
-    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
-    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_TAPI_ID))
-    config_rules = [
-        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
-        for config_rule in device_data.device_config.config_rules
-    ]
-    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
-        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
-    for config_rule in DEVICE_TAPI_DECONFIG_RULES:
-        action_set = ConfigActionEnum.Name(ConfigActionEnum.CONFIGACTION_SET)
-        config_rule = (action_set, config_rule['resource_key'], config_rule['resource_value'])
-        assert config_rule not in config_rules
-
-
-def test_device_tapi_delete(
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
-
-    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
-
-    device_client.DeleteDevice(DeviceId(**DEVICE_TAPI_ID))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_TAPI_UUID, {})
-    assert driver is None
-
-
-# ----- Test Device Driver P4 --------------------------------------------------
-
-def test_device_p4_add_error_cases(
-        context_client: ContextClient,   # pylint: disable=redefined-outer-name
-        device_client: DeviceClient,     # pylint: disable=redefined-outer-name
-        device_service: DeviceService):  # pylint: disable=redefined-outer-name
-
-    if not ENABLE_P4: pytest.skip(
-        'Skipping test: No P4 device has been configured')
-
-    with pytest.raises(grpc.RpcError) as e:
-        device_p4_with_extra_rules = copy.deepcopy(DEVICE_P4)
-        device_p4_with_extra_rules['device_config']['config_rules'].extend(
-            DEVICE_P4_CONNECT_RULES)
-        device_p4_with_extra_rules['device_config']['config_rules'].extend(
-            DEVICE_P4_CONFIG_RULES)
-        device_client.AddDevice(Device(**device_p4_with_extra_rules))
-    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
-    msg_head = 'device.device_config.config_rules(['
-    msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\
-               'with "_connect/" tag. Others should be configured after adding the device.'
-    except_msg = str(e.value.details())
-    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
-
-
-def test_device_p4_add_correct(
-        context_client: ContextClient,              # pylint: disable=redefined-outer-name
-        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
-        device_service: DeviceService,              # pylint: disable=redefined-outer-name
-        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
-
-    if not ENABLE_P4: pytest.skip(
-        'Skipping test: No P4 device has been configured')
-
-    device_p4_with_connect_rules = copy.deepcopy(DEVICE_P4)
-    device_p4_with_connect_rules['device_config']['config_rules'].extend(
-        DEVICE_P4_CONNECT_RULES)
-    device_client.AddDevice(Device(**device_p4_with_connect_rules))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_P4_UUID)
-    assert driver is not None
-
-
-def test_device_p4_get(
-        context_client: ContextClient,              # pylint: disable=redefined-outer-name
-        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
-        device_service: DeviceService,              # pylint: disable=redefined-outer-name
-        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
-
-    if not ENABLE_P4: pytest.skip(
-        'Skipping test: No P4 device has been configured')
-
-    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_P4_ID))
-    LOGGER.info('initial_config = {:s}'.format(
-        grpc_message_to_json_string(initial_config)))
-
-    device_data = context_client.GetDevice(DeviceId(**DEVICE_P4_ID))
-    LOGGER.info('device_data = {:s}'.format(
-        grpc_message_to_json_string(device_data)))
-
-
-def test_device_p4_configure(
-        context_client: ContextClient,              # pylint: disable=redefined-outer-name
-        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
-        device_service: DeviceService,              # pylint: disable=redefined-outer-name
-        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
-
-    if not ENABLE_P4: pytest.skip(
-        'Skipping test: No P4 device has been configured')
-
-    pytest.skip('Skipping test for unimplemented method')
-
-
-def test_device_p4_deconfigure(
-        context_client: ContextClient,              # pylint: disable=redefined-outer-name
-        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
-        device_service: DeviceService,              # pylint: disable=redefined-outer-name
-        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
-
-    if not ENABLE_P4: pytest.skip(
-        'Skipping test: No P4 device has been configured')
-
-    pytest.skip('Skipping test for unimplemented method')
-
-
-def test_device_p4_delete(
-        context_client: ContextClient,              # pylint: disable=redefined-outer-name
-        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
-        device_service: DeviceService,              # pylint: disable=redefined-outer-name
-        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
-
-    if not ENABLE_P4: pytest.skip('Skipping test: No P4 device has been configured')
-
-    device_client.DeleteDevice(DeviceId(**DEVICE_P4_ID))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_P4_UUID)
-    assert driver is None
diff --git a/src/device/tests/test_unitary_emulated.py b/src/device/tests/test_unitary_emulated.py
new file mode 100644
index 000000000..67a2e9c33
--- /dev/null
+++ b/src/device/tests/test_unitary_emulated.py
@@ -0,0 +1,378 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import calendar, copy, dateutil.parser, grpc, json, logging, operator, pytest, queue, time
+from datetime import datetime, timezone
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import DeviceId, DeviceOperationalStatusEnum
+from device.client.DeviceClient import DeviceClient
+from device.proto.context_pb2 import ConfigActionEnum, Device
+from device.proto.device_pb2 import MonitoringSettings
+from device.proto.kpi_sample_types_pb2 import KpiSampleType
+from device.service.DeviceService import DeviceService
+from device.service.driver_api._Driver import _Driver
+from .MockService_Dependencies import MockService_Dependencies
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    mock_service, device_service, context_client, device_client, monitoring_client, test_prepare_environment)
+
+from .Device_Emulated import (
+    DEVICE_EMU, DEVICE_EMU_CONFIG_ADDRESSES, DEVICE_EMU_CONFIG_ENDPOINTS, DEVICE_EMU_CONNECT_RULES,
+    DEVICE_EMU_DECONFIG_ADDRESSES, DEVICE_EMU_DECONFIG_ENDPOINTS, DEVICE_EMU_ENDPOINTS_COOKED, DEVICE_EMU_ID,
+    DEVICE_EMU_RECONFIG_ADDRESSES, DEVICE_EMU_UUID)
+
+logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING)
+logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING)
+logging.getLogger('monitoring-client').setLevel(logging.WARNING)
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+# ----- Test Device Driver Emulated --------------------------------------------
+# Device Driver Emulated tests are used to validate Driver API as well as Emulated Device Driver. Note that other
+# Drivers might support a different set of resource paths, and attributes/values per resource; however, they must
+# implement the Driver API.
+
+def test_device_emulated_add_error_cases(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    with pytest.raises(grpc.RpcError) as e:
+        DEVICE_EMU_WITH_ENDPOINTS = copy.deepcopy(DEVICE_EMU)
+        DEVICE_EMU_WITH_ENDPOINTS['device_endpoints'].append(json_endpoint(DEVICE_EMU_ID, 'ep-id', 'ep-type'))
+        device_client.AddDevice(Device(**DEVICE_EMU_WITH_ENDPOINTS))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg_head = 'device.device_endpoints(['
+    msg_tail = ']) is invalid; RPC method AddDevice does not accept Endpoints. '\
+               'Endpoints are discovered through interrogation of the physical device.'
+    except_msg = str(e.value.details())
+    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
+
+    with pytest.raises(grpc.RpcError) as e:
+        DEVICE_EMU_WITH_EXTRA_RULES = copy.deepcopy(DEVICE_EMU)
+        DEVICE_EMU_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONNECT_RULES)
+        DEVICE_EMU_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONFIG_ENDPOINTS)
+        device_client.AddDevice(Device(**DEVICE_EMU_WITH_EXTRA_RULES))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg_head = 'device.device_config.config_rules(['
+    msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\
+               'with "_connect/" tag. Others should be configured after adding the device.'
+    except_msg = str(e.value.details())
+    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
+
+
+def test_device_emulated_add_correct(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    DEVICE_EMU_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_EMU)
+    DEVICE_EMU_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONNECT_RULES)
+    device_client.AddDevice(Device(**DEVICE_EMU_WITH_CONNECT_RULES))
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_EMU_UUID) # we know the driver exists now
+    assert driver is not None
+
+
+def test_device_emulated_get(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_EMU_ID))
+    LOGGER.info('initial_config = {:s}'.format(grpc_message_to_json_string(initial_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID))
+    LOGGER.info('device_data = {:s}'.format(grpc_message_to_json_string(device_data)))
+
+
+def test_device_emulated_configure(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_EMU_UUID) # we know the driver exists now
+    assert driver is not None
+
+    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+    assert len(driver_config) == len(DEVICE_EMU_ENDPOINTS_COOKED)
+    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
+        assert endpoint_cooked in driver_config
+
+    DEVICE_EMU_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_EMU)
+    DEVICE_EMU_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONFIG_ENDPOINTS)
+    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_CONFIG_RULES))
+
+    DEVICE_EMU_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_EMU)
+    DEVICE_EMU_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_CONFIG_ADDRESSES)
+    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_CONFIG_RULES))
+
+    DEVICE_EMU_WITH_OPERATIONAL_STATUS = copy.deepcopy(DEVICE_EMU)
+    DEVICE_EMU_WITH_OPERATIONAL_STATUS['device_operational_status'] = \
+        DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_OPERATIONAL_STATUS))
+
+    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+    assert len(driver_config) == len(DEVICE_EMU_ENDPOINTS_COOKED) + len(DEVICE_EMU_CONFIG_ADDRESSES)
+    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
+        endpoint_cooked = copy.deepcopy(endpoint_cooked)
+        endpoint_cooked[1]['enabled'] = True
+        assert endpoint_cooked in driver_config
+    for config_rule in DEVICE_EMU_CONFIG_ADDRESSES:
+        assert (config_rule['resource_key'], json.loads(config_rule['resource_value'])) in driver_config
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID))
+    assert device_data.device_operational_status == DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    #LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+    #    '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+    RESULTING_CONFIG_ENDPOINTS = {cr['resource_key']:cr for cr in copy.deepcopy(DEVICE_EMU_CONFIG_ENDPOINTS)}
+    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
+        values = json.loads(RESULTING_CONFIG_ENDPOINTS[endpoint_cooked[0]]['resource_value'])
+        values.update(endpoint_cooked[1])
+        RESULTING_CONFIG_ENDPOINTS[endpoint_cooked[0]]['resource_value'] = json.dumps(values, sort_keys=True)
+    for config_rule in RESULTING_CONFIG_ENDPOINTS.values():
+        config_rule = (
+            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'],
+            json.loads(json.dumps(config_rule['resource_value'])))
+        assert config_rule in config_rules
+    for config_rule in DEVICE_EMU_CONFIG_ADDRESSES:
+        config_rule = (
+            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'],
+            json.loads(json.dumps(config_rule['resource_value'])))
+        assert config_rule in config_rules
+
+    # Try to reconfigure...
+
+    DEVICE_EMU_WITH_RECONFIG_RULES = copy.deepcopy(DEVICE_EMU)
+    DEVICE_EMU_WITH_RECONFIG_RULES['device_operational_status'] = \
+        DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_ENABLED
+    DEVICE_EMU_WITH_RECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_RECONFIG_ADDRESSES)
+    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_RECONFIG_RULES))
+
+    RESULTING_CONFIG_RULES = {cr['resource_key']:cr for cr in copy.deepcopy(DEVICE_EMU_CONFIG_ENDPOINTS)}
+    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
+        values = json.loads(RESULTING_CONFIG_RULES[endpoint_cooked[0]]['resource_value'])
+        values.update(endpoint_cooked[1])
+        RESULTING_CONFIG_RULES[endpoint_cooked[0]]['resource_value'] = json.dumps(values, sort_keys=True)
+    RESULTING_CONFIG_RULES.update({cr['resource_key']:cr for cr in copy.deepcopy(DEVICE_EMU_CONFIG_ADDRESSES)})
+    for reconfig_rule in DEVICE_EMU_RECONFIG_ADDRESSES:
+        if reconfig_rule['action'] == ConfigActionEnum.CONFIGACTION_DELETE:
+            RESULTING_CONFIG_RULES.pop(reconfig_rule['resource_key'], None)
+        else:
+            RESULTING_CONFIG_RULES[reconfig_rule['resource_key']] = reconfig_rule
+    RESULTING_CONFIG_RULES = RESULTING_CONFIG_RULES.values()
+    #LOGGER.info('RESULTING_CONFIG_RULES = {:s}'.format(str(RESULTING_CONFIG_RULES)))
+
+    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    driver_config = json.loads(json.dumps(driver_config)) # prevent integer keys to fail matching with string keys
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+    assert len(driver_config) == len(RESULTING_CONFIG_RULES)
+    for config_rule in RESULTING_CONFIG_RULES:
+        resource = [config_rule['resource_key'], json.loads(config_rule['resource_value'])]
+        assert resource in driver_config
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    #LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+    #    '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+    for config_rule in RESULTING_CONFIG_RULES:
+        config_rule = (
+            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value'])
+        assert config_rule in config_rules
+
+
+def test_device_emulated_monitor(
+    context_client : ContextClient,         # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,           # pylint: disable=redefined-outer-name
+    device_service : DeviceService,         # pylint: disable=redefined-outer-name
+    mock_service : MockService_Dependencies):   # pylint: disable=redefined-outer-name
+
+    device_uuid = DEVICE_EMU_UUID
+    json_device_id = DEVICE_EMU_ID
+    device_id = DeviceId(**json_device_id)
+    device_data = context_client.GetDevice(device_id)
+    LOGGER.info('device_data = \n{:s}'.format(str(device_data)))
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(device_uuid) # we know the driver exists now
+    assert driver is not None
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+    #assert len(driver_config) == len(DEVICE_EMU_ENDPOINTS_COOKED) + len(DEVICE_EMU_CONFIG_ADDRESSES)
+
+    SAMPLING_DURATION_SEC = 10.0
+    SAMPLING_INTERVAL_SEC = 2.0
+
+    MONITORING_SETTINGS_LIST = []
+    KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {}
+    for endpoint in device_data.device_endpoints:
+        endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
+        for sample_type_id in endpoint.kpi_sample_types:
+            sample_type_name = str(KpiSampleType.Name(sample_type_id)).upper().replace('KPISAMPLETYPE_', '')
+            kpi_uuid = '{:s}-{:s}-{:s}-kpi_uuid'.format(device_uuid, endpoint_uuid, str(sample_type_id))
+            monitoring_settings = {
+                'kpi_id'        : {'kpi_id': {'uuid': kpi_uuid}},
+                'kpi_descriptor': {
+                    'kpi_description': 'Metric {:s} for Endpoint {:s} in Device {:s}'.format(
+                        sample_type_name, endpoint_uuid, device_uuid),
+                    'kpi_sample_type': sample_type_id,
+                    'device_id': json_device_id,
+                    'endpoint_id': json_endpoint_id(json_device_id, endpoint_uuid),
+                },
+                'sampling_duration_s': SAMPLING_DURATION_SEC,
+                'sampling_interval_s': SAMPLING_INTERVAL_SEC,
+            }
+            MONITORING_SETTINGS_LIST.append(monitoring_settings)
+            KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] = 0
+
+    NUM_SAMPLES_EXPECTED_PER_KPI = SAMPLING_DURATION_SEC / SAMPLING_INTERVAL_SEC
+    NUM_SAMPLES_EXPECTED = len(MONITORING_SETTINGS_LIST) * NUM_SAMPLES_EXPECTED_PER_KPI
+
+    # Start monitoring the device
+    t_start_monitoring = datetime.timestamp(datetime.utcnow())
+    for monitoring_settings in MONITORING_SETTINGS_LIST:
+        device_client.MonitorDeviceKpi(MonitoringSettings(**monitoring_settings))
+
+    # wait to receive the expected number of samples
+    # if takes more than 1.5 times the sampling duration, assume there is an error
+    time_ini = time.time()
+    queue_samples : queue.Queue = mock_service.queue_samples
+    received_samples = []
+    while (len(received_samples) < NUM_SAMPLES_EXPECTED) and (time.time() - time_ini < SAMPLING_DURATION_SEC * 1.5):
+        try:
+            received_sample = queue_samples.get(block=True, timeout=SAMPLING_INTERVAL_SEC / NUM_SAMPLES_EXPECTED)
+            #LOGGER.info('received_sample = {:s}'.format(str(received_sample)))
+            received_samples.append(received_sample)
+        except queue.Empty:
+            continue
+
+    t_end_monitoring = datetime.timestamp(datetime.utcnow())
+
+    #LOGGER.info('received_samples = {:s}'.format(str(received_samples)))
+    LOGGER.info('len(received_samples) = {:s}'.format(str(len(received_samples))))
+    LOGGER.info('NUM_SAMPLES_EXPECTED = {:s}'.format(str(NUM_SAMPLES_EXPECTED)))
+    assert len(received_samples) == NUM_SAMPLES_EXPECTED
+    for received_sample in received_samples:
+        kpi_uuid = received_sample.kpi_id.kpi_id.uuid
+        assert kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED
+        assert isinstance(received_sample.timestamp, str)
+        try:
+            timestamp = float(received_sample.timestamp)
+        except ValueError:
+            dt_time = dateutil.parser.isoparse(received_sample.timestamp).replace(tzinfo=timezone.utc)
+            timestamp = float(calendar.timegm(dt_time.timetuple())) + (dt_time.microsecond / 1.e6)
+        assert timestamp > t_start_monitoring
+        assert timestamp < t_end_monitoring
+        assert received_sample.kpi_value.HasField('floatVal') or received_sample.kpi_value.HasField('intVal')
+        kpi_value = getattr(received_sample.kpi_value, received_sample.kpi_value.WhichOneof('value'))
+        assert isinstance(kpi_value, (float, int))
+        KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] += 1
+
+    LOGGER.info('KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {:s}'.format(str(KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED)))
+    for kpi_uuid, num_samples_received in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED.items():
+        assert num_samples_received == NUM_SAMPLES_EXPECTED_PER_KPI
+
+    # Unsubscribe monitoring
+    for kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED.keys():
+        MONITORING_SETTINGS_UNSUBSCRIBE = {
+            'kpi_id'             : {'kpi_id': {'uuid': kpi_uuid}},
+            'sampling_duration_s': -1, # negative value in sampling_duration_s or sampling_interval_s means unsibscribe
+            'sampling_interval_s': -1, # kpi_id is mandatory to unsibscribe
+        }
+        device_client.MonitorDeviceKpi(MonitoringSettings(**MONITORING_SETTINGS_UNSUBSCRIBE))
+
+
+def test_device_emulated_deconfigure(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_EMU_UUID) # we know the driver exists now
+    assert driver is not None
+
+    driver_config = driver.GetConfig()
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    DEVICE_EMU_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_EMU)
+    DEVICE_EMU_WITH_DECONFIG_RULES['device_operational_status'] = \
+        DeviceOperationalStatusEnum.DEVICEOPERATIONALSTATUS_DISABLED
+    DEVICE_EMU_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_DECONFIG_ADDRESSES)
+    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_DECONFIG_RULES))
+
+    RESULTING_CONFIG_RULES = {cr['resource_key']:cr for cr in copy.deepcopy(DEVICE_EMU_CONFIG_ENDPOINTS)}
+    for endpoint_cooked in DEVICE_EMU_ENDPOINTS_COOKED:
+        values = json.loads(RESULTING_CONFIG_RULES[endpoint_cooked[0]]['resource_value'])
+        values.update(endpoint_cooked[1])
+        RESULTING_CONFIG_RULES[endpoint_cooked[0]]['resource_value'] = json.dumps(values, sort_keys=True)
+    RESULTING_CONFIG_RULES = RESULTING_CONFIG_RULES.values()
+    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    driver_config = json.loads(json.dumps(driver_config)) # prevent integer keys to fail matching with string keys
+    driver_config = list(filter(
+        lambda config_rule: (
+            not isinstance(config_rule[1], str) or not config_rule[1].startswith('do_sampling (trigger:')),
+        driver_config))
+    LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+    LOGGER.info('RESULTING_CONFIG_RULES = {:s}'.format(str(RESULTING_CONFIG_RULES)))
+    assert len(driver_config) == len(RESULTING_CONFIG_RULES)
+    for config_rule in RESULTING_CONFIG_RULES:
+        config_rule = [config_rule['resource_key'], json.loads(config_rule['resource_value'])]
+        #LOGGER.info('config_rule = {:s}'.format(str(config_rule)))
+        assert config_rule in driver_config
+
+    DEVICE_EMU_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_EMU)
+    DEVICE_EMU_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_EMU_DECONFIG_ENDPOINTS)
+    device_client.ConfigureDevice(Device(**DEVICE_EMU_WITH_DECONFIG_RULES))
+
+    driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    driver_config = json.loads(json.dumps(driver_config)) # prevent integer keys to fail matching with string keys
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+    assert len(driver_config) == 0
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_EMU_ID))
+    config_rules = device_data.device_config.config_rules
+    LOGGER.info('config_rules = {:s}'.format(str(config_rules)))
+    clean_config_rules = []
+    for config_rule in config_rules:
+        if config_rule.resource_key.startswith('/endpoints/endpoint'): continue
+        config_rule_value = json.loads(config_rule.resource_value)
+        if isinstance(config_rule_value, str) and config_rule_value.startswith('do_sampling (trigger:'): continue
+        clean_config_rules.append(config_rule)
+    LOGGER.info('clean_config_rules = {:s}'.format(str(clean_config_rules)))
+    assert len(clean_config_rules) == 0
+
+
+def test_device_emulated_delete(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    device_client.DeleteDevice(DeviceId(**DEVICE_EMU_ID))
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_EMU_UUID, {})
+    assert driver is None
diff --git a/src/device/tests/test_unitary_microwave.py b/src/device/tests/test_unitary_microwave.py
index 8718d99fb..c5cd70b99 100644
--- a/src/device/tests/test_unitary_microwave.py
+++ b/src/device/tests/test_unitary_microwave.py
@@ -12,211 +12,61 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import calendar, copy, dateutil.parser, grpc, json, logging, operator, os, pytest, queue, time
-from datetime import datetime, timezone
-from typing import Tuple
-from common.orm.Database import Database
-from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
-from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
-from common.message_broker.MessageBroker import MessageBroker
+import copy, grpc, logging, pytest
 from common.tools.grpc.Tools import grpc_message_to_json_string
-from common.tools.object_factory.EndPoint import json_endpoint, json_endpoint_id
-from context.Config import (
-    GRPC_SERVICE_PORT as CONTEXT_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as CONTEXT_GRPC_MAX_WORKERS,
-    GRPC_GRACE_PERIOD as CONTEXT_GRPC_GRACE_PERIOD)
 from context.client.ContextClient import ContextClient
-from context.proto.context_pb2 import DeviceId, DeviceOperationalStatusEnum
-from context.service.grpc_server.ContextService import ContextService
-from device.Config import (
-    GRPC_SERVICE_PORT as DEVICE_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as DEVICE_GRPC_MAX_WORKERS,
-    GRPC_GRACE_PERIOD as DEVICE_GRPC_GRACE_PERIOD)
+from context.proto.context_pb2 import DeviceId
 from device.client.DeviceClient import DeviceClient
-from device.proto.context_pb2 import ConfigActionEnum, Context, Device, Topology
-from device.proto.device_pb2 import MonitoringSettings
-from device.proto.kpi_sample_types_pb2 import KpiSampleType
+from device.proto.context_pb2 import ConfigActionEnum, Device
 from device.service.DeviceService import DeviceService
 from device.service.driver_api._Driver import _Driver
-from device.service.driver_api.DriverFactory import DriverFactory
-from device.service.driver_api.DriverInstanceCache import DriverInstanceCache
-from device.service.drivers import DRIVERS
-from device.tests.MockMonitoringService import MockMonitoringService
-from monitoring.Config import (
-    GRPC_SERVICE_PORT as MONITORING_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as MONITORING_GRPC_MAX_WORKERS,
-    GRPC_GRACE_PERIOD as MONITORING_GRPC_GRACE_PERIOD)
-from monitoring.client.monitoring_client import MonitoringClient
-from .CommonObjects import CONTEXT, TOPOLOGY
-
-from .Device_Emulated import (
-    DEVICE_EMU, DEVICE_EMU_CONFIG_ADDRESSES, DEVICE_EMU_CONFIG_ENDPOINTS, DEVICE_EMU_CONNECT_RULES,
-    DEVICE_EMU_DECONFIG_ADDRESSES, DEVICE_EMU_DECONFIG_ENDPOINTS, DEVICE_EMU_EP_DESCS, DEVICE_EMU_ENDPOINTS_COOKED,
-    DEVICE_EMU_ID, DEVICE_EMU_RECONFIG_ADDRESSES, DEVICE_EMU_UUID)
-ENABLE_EMULATED = True
-
-try:
-    from .Device_OpenConfig_Infinera1 import(
-    #from .Device_OpenConfig_Infinera2 import(
-        DEVICE_OC, DEVICE_OC_CONFIG_RULES, DEVICE_OC_DECONFIG_RULES, DEVICE_OC_CONNECT_RULES, DEVICE_OC_ID,
-        DEVICE_OC_UUID)
-    ENABLE_OPENCONFIG = True
-except ImportError:
-    ENABLE_OPENCONFIG = False
-
-try:
-    from .Device_Transport_Api_CTTC import (
-        DEVICE_TAPI, DEVICE_TAPI_CONNECT_RULES, DEVICE_TAPI_UUID, DEVICE_TAPI_ID, DEVICE_TAPI_CONFIG_RULES,
-        DEVICE_TAPI_DECONFIG_RULES)
-    ENABLE_TAPI = True
-except ImportError:
-    ENABLE_TAPI = False
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    mock_service, device_service, context_client, device_client, monitoring_client, test_prepare_environment)
 
 try:
     from .Device_Microwave_Template import (
-        DEVICE_MICROWAVE, DEVICE_MICROWAVE_CONNECT_RULES, DEVICE_MICROWAVE_UUID, DEVICE_MICROWAVE_ID, DEVICE_MICROWAVE_CONFIG_RULES,
-        DEVICE_MICROWAVE_DECONFIG_RULES)
+        DEVICE_MICROWAVE, DEVICE_MICROWAVE_CONNECT_RULES, DEVICE_MICROWAVE_UUID, DEVICE_MICROWAVE_ID,
+        DEVICE_MICROWAVE_CONFIG_RULES, DEVICE_MICROWAVE_DECONFIG_RULES)
     ENABLE_MICROWAVE = True
-except ImportError as error:
-    ENABLE_MICROWAVE = False
-    print(error.__class__.__name__ + ": " + error.message)
-
-from .mock_p4runtime_service import MockP4RuntimeService
-try:
-    from .device_p4 import(
-        DEVICE_P4, DEVICE_P4_ID, DEVICE_P4_UUID, DEVICE_P4_NAME, DEVICE_P4_ADDRESS, DEVICE_P4_PORT, DEVICE_P4_WORKERS,
-        DEVICE_P4_GRACE_PERIOD, DEVICE_P4_CONNECT_RULES, DEVICE_P4_CONFIG_RULES)
-    ENABLE_P4 = True
 except ImportError:
-    ENABLE_P4 = False
-
-#ENABLE_EMULATED   = False # set to False to disable tests of Emulated devices
-#ENABLE_OPENCONFIG = False # set to False to disable tests of OpenConfig devices
-#ENABLE_TAPI       = False # set to False to disable tests of TAPI devices
-#ENABLE_P4         = False # set to False to disable tests of P4 devices
-
-ENABLE_OPENCONFIG_CONFIGURE   = True
-ENABLE_OPENCONFIG_MONITOR     = True
-ENABLE_OPENCONFIG_DECONFIGURE = True
-
-
-logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING)
-logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING)
-logging.getLogger('monitoring-client').setLevel(logging.WARNING)
+    ENABLE_MICROWAVE = False
 
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
 
-CONTEXT_GRPC_SERVICE_PORT = 10000 + CONTEXT_GRPC_SERVICE_PORT # avoid privileged ports
-DEVICE_GRPC_SERVICE_PORT = 10000 + DEVICE_GRPC_SERVICE_PORT # avoid privileged ports
-MONITORING_GRPC_SERVICE_PORT = 10000 + MONITORING_GRPC_SERVICE_PORT # avoid privileged ports
-
-DEFAULT_REDIS_SERVICE_HOST = '127.0.0.1'
-DEFAULT_REDIS_SERVICE_PORT = 6379
-DEFAULT_REDIS_DATABASE_ID  = 0
-
-REDIS_CONFIG = {
-    'REDIS_SERVICE_HOST': os.environ.get('REDIS_SERVICE_HOST', DEFAULT_REDIS_SERVICE_HOST),
-    'REDIS_SERVICE_PORT': os.environ.get('REDIS_SERVICE_PORT', DEFAULT_REDIS_SERVICE_PORT),
-    'REDIS_DATABASE_ID' : os.environ.get('REDIS_DATABASE_ID',  DEFAULT_REDIS_DATABASE_ID ),
-}
-
-SCENARIOS = [
-    ('all_inmemory', DatabaseBackendEnum.INMEMORY, {},           MessageBrokerBackendEnum.INMEMORY, {}          ),
-    #('all_redis',    DatabaseBackendEnum.REDIS,    REDIS_CONFIG, MessageBrokerBackendEnum.REDIS,    REDIS_CONFIG),
-]
-
-@pytest.fixture(scope='session', ids=[str(scenario[0]) for scenario in SCENARIOS], params=SCENARIOS)
-def context_db_mb(request) -> Tuple[Database, MessageBroker]:
-    name,db_backend,db_settings,mb_backend,mb_settings = request.param
-    msg = 'Running scenario {:s} db_backend={:s}, db_settings={:s}, mb_backend={:s}, mb_settings={:s}...'
-    LOGGER.info(msg.format(str(name), str(db_backend.value), str(db_settings), str(mb_backend.value), str(mb_settings)))
-    _database = Database(get_database_backend(backend=db_backend, **db_settings))
-    _message_broker = MessageBroker(get_messagebroker_backend(backend=mb_backend, **mb_settings))
-    yield _database, _message_broker
-    _message_broker.terminate()
-
-@pytest.fixture(scope='session')
-def context_service(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
-    _service = ContextService(
-        context_db_mb[0], context_db_mb[1], port=CONTEXT_GRPC_SERVICE_PORT, max_workers=CONTEXT_GRPC_MAX_WORKERS,
-        grace_period=CONTEXT_GRPC_GRACE_PERIOD)
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def context_client(context_service : ContextService): # pylint: disable=redefined-outer-name
-    _client = ContextClient(address='127.0.0.1', port=CONTEXT_GRPC_SERVICE_PORT)
-    yield _client
-    _client.close()
-
-@pytest.fixture(scope='session')
-def monitoring_service():
-    _service = MockMonitoringService(port=MONITORING_GRPC_SERVICE_PORT, max_workers=MONITORING_GRPC_MAX_WORKERS,
-        grace_period=MONITORING_GRPC_GRACE_PERIOD)
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def monitoring_client(monitoring_service : MockMonitoringService): # pylint: disable=redefined-outer-name
-    _client = MonitoringClient(server='127.0.0.1', port=MONITORING_GRPC_SERVICE_PORT)
-    #yield _client
-    #_client.close()
-    return _client
-
-@pytest.fixture(scope='session')
-def device_service(
-    context_client : ContextClient,         # pylint: disable=redefined-outer-name
-    monitoring_client : MonitoringClient):  # pylint: disable=redefined-outer-name
-
-    _driver_factory = DriverFactory(DRIVERS)
-    _driver_instance_cache = DriverInstanceCache(_driver_factory)
-    _service = DeviceService(
-        context_client, monitoring_client, _driver_instance_cache, port=DEVICE_GRPC_SERVICE_PORT,
-        max_workers=DEVICE_GRPC_MAX_WORKERS, grace_period=DEVICE_GRPC_GRACE_PERIOD)
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def device_client(device_service : DeviceService): # pylint: disable=redefined-outer-name
-    _client = DeviceClient(address='127.0.0.1', port=DEVICE_GRPC_SERVICE_PORT)
-    yield _client
-    _client.close()
-
-@pytest.fixture(scope='session')
-def p4runtime_service():
-    _service = MockP4RuntimeService(
-        address=DEVICE_P4_ADDRESS, port=DEVICE_P4_PORT,
-        max_workers=DEVICE_P4_WORKERS,
-        grace_period=DEVICE_P4_GRACE_PERIOD)
-    _service.start()
-    yield _service
-    _service.stop()
-
-
-def test_prepare_environment(
-    context_client : ContextClient,     # pylint: disable=redefined-outer-name
-    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
-    device_service : DeviceService):    # pylint: disable=redefined-outer-name
 
-    context_client.SetContext(Context(**CONTEXT))
-    context_client.SetTopology(Topology(**TOPOLOGY))
+# ----- Test Device Driver Microwave ------------------------------------------------
 
+def test_device_microwave_add_error_cases(
+    device_client : DeviceClient):      # pylint: disable=redefined-outer-name
 
+    if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No TAPI device has been configured')
 
+    with pytest.raises(grpc.RpcError) as e:
+        DEVICE_MICROWAVE_WITH_EXTRA_RULES = copy.deepcopy(DEVICE_MICROWAVE)
+        DEVICE_MICROWAVE_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_MICROWAVE_CONNECT_RULES)
+        DEVICE_MICROWAVE_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_MICROWAVE_CONFIG_RULES)
+        device_client.AddDevice(Device(**DEVICE_MICROWAVE_WITH_EXTRA_RULES))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg_head = 'device.device_config.config_rules(['
+    msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\
+               'with "_connect/" tag. Others should be configured after adding the device.'
+    except_msg = str(e.value.details())
+    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
 
-# ----- Test Device Driver Microwave ------------------------------------------------
 
 def test_device_microwave_add_correct(
     device_client: DeviceClient,        # pylint: disable=redefined-outer-name
     device_service: DeviceService):     # pylint: disable=redefined-outer-name
 
     if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No MICROWAVE device has been configured')
-    
+
     DEVICE_MICROWAVE_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_MICROWAVE)
     DEVICE_MICROWAVE_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_MICROWAVE_CONNECT_RULES)
     device_client.AddDevice(Device(**DEVICE_MICROWAVE_WITH_CONNECT_RULES))
-    driver: _Driver = device_service.driver_instance_cache.get(DEVICE_MICROWAVE_UUID)
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver: _Driver = driver_instance_cache.get(DEVICE_MICROWAVE_UUID)
     assert driver is not None
 
 
@@ -240,7 +90,8 @@ def test_device_microwave_configure(
 
     if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No MICROWAVE device has been configured')
 
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_MICROWAVE_UUID)
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_MICROWAVE_UUID)
     assert driver is not None
 
     # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
@@ -263,8 +114,6 @@ def test_device_microwave_configure(
     LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
         '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
     for config_rule in DEVICE_MICROWAVE_CONFIG_RULES:
-        #import pdb;
-        #pdb. set_trace()
         config_rule = (
             ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value'])
         assert config_rule in config_rules
@@ -277,7 +126,8 @@ def test_device_microwave_deconfigure(
 
     if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No MICROWAVE device has been configured')
 
-    driver: _Driver = device_service.driver_instance_cache.get(DEVICE_MICROWAVE_UUID)
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver: _Driver = driver_instance_cache.get(DEVICE_MICROWAVE_UUID)
     assert driver is not None
 
     # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
@@ -312,5 +162,6 @@ def test_device_microwave_delete(
     if not ENABLE_MICROWAVE: pytest.skip('Skipping test: No MICROWAVE device has been configured')
 
     device_client.DeleteDevice(DeviceId(**DEVICE_MICROWAVE_ID))
-    driver : _Driver = device_service.driver_instance_cache.get(DEVICE_MICROWAVE_UUID, {})
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_MICROWAVE_UUID, {})
     assert driver is None
\ No newline at end of file
diff --git a/src/device/tests/test_unitary_openconfig.py b/src/device/tests/test_unitary_openconfig.py
new file mode 100644
index 000000000..968272c04
--- /dev/null
+++ b/src/device/tests/test_unitary_openconfig.py
@@ -0,0 +1,299 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import calendar, copy, dateutil.parser, grpc, logging, pytest, queue, time
+from datetime import datetime, timezone
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from common.tools.object_factory.EndPoint import json_endpoint_id
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import DeviceId
+from device.client.DeviceClient import DeviceClient
+from device.proto.context_pb2 import ConfigActionEnum, Device
+from device.proto.device_pb2 import MonitoringSettings
+from device.proto.kpi_sample_types_pb2 import KpiSampleType
+from device.service.DeviceService import DeviceService
+from device.service.driver_api._Driver import _Driver
+from .MockService_Dependencies import MockService_Dependencies
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    mock_service, device_service, context_client, device_client, monitoring_client, test_prepare_environment)
+
+try:
+    from .Device_OpenConfig_Infinera1 import(
+    #from .Device_OpenConfig_Infinera2 import(
+        DEVICE_OC, DEVICE_OC_CONFIG_RULES, DEVICE_OC_DECONFIG_RULES, DEVICE_OC_CONNECT_RULES, DEVICE_OC_ID,
+        DEVICE_OC_UUID)
+    ENABLE_OPENCONFIG = True
+except ImportError:
+    ENABLE_OPENCONFIG = False
+
+ENABLE_OPENCONFIG_CONFIGURE   = True
+ENABLE_OPENCONFIG_MONITOR     = True
+ENABLE_OPENCONFIG_DECONFIGURE = True
+
+
+logging.getLogger('apscheduler.executors.default').setLevel(logging.WARNING)
+logging.getLogger('apscheduler.scheduler').setLevel(logging.WARNING)
+logging.getLogger('monitoring-client').setLevel(logging.WARNING)
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+
+# ----- Test Device Driver OpenConfig ------------------------------------------
+
+def test_device_openconfig_add_error_cases(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+
+    with pytest.raises(grpc.RpcError) as e:
+        DEVICE_OC_WITH_EXTRA_RULES = copy.deepcopy(DEVICE_OC)
+        DEVICE_OC_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONNECT_RULES)
+        DEVICE_OC_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONFIG_RULES)
+        device_client.AddDevice(Device(**DEVICE_OC_WITH_EXTRA_RULES))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg_head = 'device.device_config.config_rules(['
+    msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\
+               'with "_connect/" tag. Others should be configured after adding the device.'
+    except_msg = str(e.value.details())
+    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
+
+
+def test_device_openconfig_add_correct(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+
+    DEVICE_OC_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_OC)
+    DEVICE_OC_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONNECT_RULES)
+    device_client.AddDevice(Device(**DEVICE_OC_WITH_CONNECT_RULES))
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now
+    assert driver is not None
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+
+
+def test_device_openconfig_get(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+
+    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_OC_ID))
+    LOGGER.info('initial_config = {:s}'.format(grpc_message_to_json_string(initial_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID))
+    LOGGER.info('device_data = {:s}'.format(grpc_message_to_json_string(device_data)))
+
+
+def test_device_openconfig_configure(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+    if not ENABLE_OPENCONFIG_CONFIGURE: pytest.skip('Skipping test OpenConfig configure')
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now
+    assert driver is not None
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    DEVICE_OC_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_OC)
+    DEVICE_OC_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_OC_CONFIG_RULES)
+    device_client.ConfigureDevice(Device(**DEVICE_OC_WITH_CONFIG_RULES))
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+    for config_rule in DEVICE_OC_CONFIG_RULES:
+        config_rule = (
+            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value'])
+        assert config_rule in config_rules
+
+
+def test_device_openconfig_monitor(
+    context_client : ContextClient,             # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,               # pylint: disable=redefined-outer-name
+    device_service : DeviceService,             # pylint: disable=redefined-outer-name
+    mock_service : MockService_Dependencies):   # pylint: disable=redefined-outer-name
+
+    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+    if not ENABLE_OPENCONFIG_MONITOR: pytest.skip('Skipping test OpenConfig monitor')
+
+    device_uuid = DEVICE_OC_UUID
+    json_device_id = DEVICE_OC_ID
+    device_id = DeviceId(**json_device_id)
+    device_data = context_client.GetDevice(device_id)
+    #LOGGER.info('device_data = \n{:s}'.format(str(device_data)))
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(device_uuid) # we know the driver exists now
+    assert driver is not None
+
+    SAMPLING_DURATION_SEC = 60.0
+    SAMPLING_INTERVAL_SEC = 15.0
+
+    MONITORING_SETTINGS_LIST = []
+    KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {}
+    for endpoint in device_data.device_endpoints:
+        endpoint_uuid = endpoint.endpoint_id.endpoint_uuid.uuid
+        for sample_type_id in endpoint.kpi_sample_types:
+            sample_type_name = str(KpiSampleType.Name(sample_type_id)).upper().replace('KPISAMPLETYPE_', '')
+            kpi_uuid = '{:s}-{:s}-{:s}-kpi_uuid'.format(device_uuid, endpoint_uuid, str(sample_type_id))
+            monitoring_settings = {
+                'kpi_id'        : {'kpi_id': {'uuid': kpi_uuid}},
+                'kpi_descriptor': {
+                    'kpi_description': 'Metric {:s} for Endpoint {:s} in Device {:s}'.format(
+                        sample_type_name, endpoint_uuid, device_uuid),
+                    'kpi_sample_type': sample_type_id,
+                    'device_id': json_device_id,
+                    'endpoint_id': json_endpoint_id(json_device_id, endpoint_uuid),
+                },
+                'sampling_duration_s': SAMPLING_DURATION_SEC,
+                'sampling_interval_s': SAMPLING_INTERVAL_SEC,
+            }
+            MONITORING_SETTINGS_LIST.append(monitoring_settings)
+            KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] = 0
+
+    NUM_SAMPLES_EXPECTED_PER_KPI = SAMPLING_DURATION_SEC / SAMPLING_INTERVAL_SEC
+    NUM_SAMPLES_EXPECTED = len(MONITORING_SETTINGS_LIST) * NUM_SAMPLES_EXPECTED_PER_KPI
+
+    # Start monitoring the device
+    t_start_monitoring = datetime.timestamp(datetime.utcnow())
+    for monitoring_settings in MONITORING_SETTINGS_LIST:
+        device_client.MonitorDeviceKpi(MonitoringSettings(**monitoring_settings))
+
+    # wait to receive the expected number of samples
+    # if takes more than 1.5 times the sampling duration, assume there is an error
+    time_ini = time.time()
+    queue_samples : queue.Queue = mock_service.queue_samples
+    received_samples = []
+    while (len(received_samples) < NUM_SAMPLES_EXPECTED) and (time.time() - time_ini < SAMPLING_DURATION_SEC * 1.5):
+        try:
+            received_sample = queue_samples.get(block=True, timeout=SAMPLING_INTERVAL_SEC / NUM_SAMPLES_EXPECTED)
+            #LOGGER.info('received_sample = {:s}'.format(str(received_sample)))
+            received_samples.append(received_sample)
+        except queue.Empty:
+            continue
+
+    t_end_monitoring = datetime.timestamp(datetime.utcnow())
+
+    #LOGGER.info('received_samples = {:s}'.format(str(received_samples)))
+    LOGGER.info('len(received_samples) = {:s}'.format(str(len(received_samples))))
+    LOGGER.info('NUM_SAMPLES_EXPECTED = {:s}'.format(str(NUM_SAMPLES_EXPECTED)))
+    #assert len(received_samples) == NUM_SAMPLES_EXPECTED
+    for received_sample in received_samples:
+        kpi_uuid = received_sample.kpi_id.kpi_id.uuid
+        assert kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED
+        assert isinstance(received_sample.timestamp, str)
+        try:
+            timestamp = float(received_sample.timestamp)
+        except ValueError:
+            dt_time = dateutil.parser.isoparse(received_sample.timestamp).replace(tzinfo=timezone.utc)
+            timestamp = float(calendar.timegm(dt_time.timetuple())) + (dt_time.microsecond / 1.e6)
+        assert timestamp > t_start_monitoring
+        assert timestamp < t_end_monitoring
+        assert received_sample.kpi_value.HasField('floatVal') or received_sample.kpi_value.HasField('intVal')
+        kpi_value = getattr(received_sample.kpi_value, received_sample.kpi_value.WhichOneof('value'))
+        assert isinstance(kpi_value, (float, int))
+        KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED[kpi_uuid] += 1
+
+    LOGGER.info('KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED = {:s}'.format(str(KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED)))
+    # TODO: review why num_samples_received per KPI != NUM_SAMPLES_EXPECTED_PER_KPI
+    #for kpi_uuid, num_samples_received in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED.items():
+    #    assert num_samples_received == NUM_SAMPLES_EXPECTED_PER_KPI
+
+    # Unsubscribe monitoring
+    for kpi_uuid in KPI_UUIDS__TO__NUM_SAMPLES_RECEIVED:
+        MONITORING_SETTINGS_UNSUBSCRIBE = {
+            'kpi_id'             : {'kpi_id': {'uuid': kpi_uuid}},
+            'sampling_duration_s': -1, # negative value in sampling_duration_s or sampling_interval_s means unsibscribe
+            'sampling_interval_s': -1, # kpi_id is mandatory to unsibscribe
+        }
+        device_client.MonitorDeviceKpi(MonitoringSettings(**MONITORING_SETTINGS_UNSUBSCRIBE))
+
+
+def test_device_openconfig_deconfigure(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+    if not ENABLE_OPENCONFIG_DECONFIGURE: pytest.skip('Skipping test OpenConfig deconfigure')
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_OC_UUID) # we know the driver exists now
+    assert driver is not None
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    DEVICE_OC_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_OC)
+    DEVICE_OC_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_OC_DECONFIG_RULES)
+    device_client.ConfigureDevice(Device(**DEVICE_OC_WITH_DECONFIG_RULES))
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_OC_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+    for config_rule in DEVICE_OC_DECONFIG_RULES:
+        action_set = ConfigActionEnum.Name(ConfigActionEnum.CONFIGACTION_SET)
+        config_rule = (action_set, config_rule['resource_key'], config_rule['resource_value'])
+        assert config_rule not in config_rules
+
+
+def test_device_openconfig_delete(
+    context_client : ContextClient,     # pylint: disable=redefined-outer-name
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    if not ENABLE_OPENCONFIG: pytest.skip('Skipping test: No OpenConfig device has been configured')
+
+    device_client.DeleteDevice(DeviceId(**DEVICE_OC_ID))
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_OC_UUID, {})
+    assert driver is None
diff --git a/src/device/tests/test_unitary_p4.py b/src/device/tests/test_unitary_p4.py
new file mode 100644
index 000000000..d8a5d37b8
--- /dev/null
+++ b/src/device/tests/test_unitary_p4.py
@@ -0,0 +1,146 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy, grpc, logging, pytest
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import DeviceId
+from device.client.DeviceClient import DeviceClient
+from device.proto.context_pb2 import Device
+from device.service.DeviceService import DeviceService
+from device.service.driver_api._Driver import _Driver
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    mock_service, device_service, context_client, device_client, monitoring_client, test_prepare_environment)
+
+from .mock_p4runtime_service import MockP4RuntimeService
+try:
+    from .device_p4 import(
+        DEVICE_P4, DEVICE_P4_ID, DEVICE_P4_UUID, DEVICE_P4_ADDRESS, DEVICE_P4_PORT, DEVICE_P4_WORKERS,
+        DEVICE_P4_GRACE_PERIOD, DEVICE_P4_CONNECT_RULES, DEVICE_P4_CONFIG_RULES)
+    ENABLE_P4 = True
+except ImportError:
+    ENABLE_P4 = False
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+@pytest.fixture(scope='session')
+def p4runtime_service():
+    _service = MockP4RuntimeService(
+        address=DEVICE_P4_ADDRESS, port=DEVICE_P4_PORT,
+        max_workers=DEVICE_P4_WORKERS,
+        grace_period=DEVICE_P4_GRACE_PERIOD)
+    _service.start()
+    yield _service
+    _service.stop()
+
+
+# ----- Test Device Driver P4 --------------------------------------------------
+
+def test_device_p4_add_error_cases(
+        context_client: ContextClient,   # pylint: disable=redefined-outer-name
+        device_client: DeviceClient,     # pylint: disable=redefined-outer-name
+        device_service: DeviceService):  # pylint: disable=redefined-outer-name
+
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
+
+    with pytest.raises(grpc.RpcError) as e:
+        device_p4_with_extra_rules = copy.deepcopy(DEVICE_P4)
+        device_p4_with_extra_rules['device_config']['config_rules'].extend(
+            DEVICE_P4_CONNECT_RULES)
+        device_p4_with_extra_rules['device_config']['config_rules'].extend(
+            DEVICE_P4_CONFIG_RULES)
+        device_client.AddDevice(Device(**device_p4_with_extra_rules))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg_head = 'device.device_config.config_rules(['
+    msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\
+               'with "_connect/" tag. Others should be configured after adding the device.'
+    except_msg = str(e.value.details())
+    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
+
+
+def test_device_p4_add_correct(
+        context_client: ContextClient,              # pylint: disable=redefined-outer-name
+        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
+        device_service: DeviceService,              # pylint: disable=redefined-outer-name
+        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
+
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
+
+    device_p4_with_connect_rules = copy.deepcopy(DEVICE_P4)
+    device_p4_with_connect_rules['device_config']['config_rules'].extend(
+        DEVICE_P4_CONNECT_RULES)
+    device_client.AddDevice(Device(**device_p4_with_connect_rules))
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_P4_UUID)
+    assert driver is not None
+
+
+def test_device_p4_get(
+        context_client: ContextClient,              # pylint: disable=redefined-outer-name
+        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
+        device_service: DeviceService,              # pylint: disable=redefined-outer-name
+        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
+
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
+
+    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_P4_ID))
+    LOGGER.info('initial_config = {:s}'.format(
+        grpc_message_to_json_string(initial_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_P4_ID))
+    LOGGER.info('device_data = {:s}'.format(
+        grpc_message_to_json_string(device_data)))
+
+
+def test_device_p4_configure(
+        context_client: ContextClient,              # pylint: disable=redefined-outer-name
+        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
+        device_service: DeviceService,              # pylint: disable=redefined-outer-name
+        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
+
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
+
+    pytest.skip('Skipping test for unimplemented method')
+
+
+def test_device_p4_deconfigure(
+        context_client: ContextClient,              # pylint: disable=redefined-outer-name
+        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
+        device_service: DeviceService,              # pylint: disable=redefined-outer-name
+        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
+
+    if not ENABLE_P4: pytest.skip(
+        'Skipping test: No P4 device has been configured')
+
+    pytest.skip('Skipping test for unimplemented method')
+
+
+def test_device_p4_delete(
+        context_client: ContextClient,              # pylint: disable=redefined-outer-name
+        device_client: DeviceClient,                # pylint: disable=redefined-outer-name
+        device_service: DeviceService,              # pylint: disable=redefined-outer-name
+        p4runtime_service: MockP4RuntimeService):   # pylint: disable=redefined-outer-name
+
+    if not ENABLE_P4: pytest.skip('Skipping test: No P4 device has been configured')
+
+    device_client.DeleteDevice(DeviceId(**DEVICE_P4_ID))
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_P4_UUID)
+    assert driver is None
diff --git a/src/device/tests/test_unitary_tapi.py b/src/device/tests/test_unitary_tapi.py
new file mode 100644
index 000000000..ce01619ce
--- /dev/null
+++ b/src/device/tests/test_unitary_tapi.py
@@ -0,0 +1,167 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import copy, grpc, logging, pytest
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from context.client.ContextClient import ContextClient
+from context.proto.context_pb2 import DeviceId
+from device.client.DeviceClient import DeviceClient
+from device.proto.context_pb2 import ConfigActionEnum, Device
+from device.service.DeviceService import DeviceService
+from device.service.driver_api._Driver import _Driver
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    mock_service, device_service, context_client, device_client, monitoring_client, test_prepare_environment)
+
+try:
+    from .Device_Transport_Api_CTTC import (
+        DEVICE_TAPI, DEVICE_TAPI_CONNECT_RULES, DEVICE_TAPI_UUID, DEVICE_TAPI_ID, DEVICE_TAPI_CONFIG_RULES,
+        DEVICE_TAPI_DECONFIG_RULES)
+    ENABLE_TAPI = True
+except ImportError:
+    ENABLE_TAPI = False
+
+LOGGER = logging.getLogger(__name__)
+LOGGER.setLevel(logging.DEBUG)
+
+
+# ----- Test Device Driver TAPI ------------------------------------------------
+
+def test_device_tapi_add_error_cases(
+    device_client : DeviceClient):      # pylint: disable=redefined-outer-name
+
+    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
+
+    with pytest.raises(grpc.RpcError) as e:
+        DEVICE_TAPI_WITH_EXTRA_RULES = copy.deepcopy(DEVICE_TAPI)
+        DEVICE_TAPI_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_CONNECT_RULES)
+        DEVICE_TAPI_WITH_EXTRA_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_CONFIG_RULES)
+        device_client.AddDevice(Device(**DEVICE_TAPI_WITH_EXTRA_RULES))
+    assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT
+    msg_head = 'device.device_config.config_rules(['
+    msg_tail = ']) is invalid; RPC method AddDevice only accepts connection Config Rules that should start '\
+               'with "_connect/" tag. Others should be configured after adding the device.'
+    except_msg = str(e.value.details())
+    assert except_msg.startswith(msg_head) and except_msg.endswith(msg_tail)
+
+
+def test_device_tapi_add_correct(
+    device_client: DeviceClient,        # pylint: disable=redefined-outer-name
+    device_service: DeviceService):     # pylint: disable=redefined-outer-name
+
+    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
+
+    DEVICE_TAPI_WITH_CONNECT_RULES = copy.deepcopy(DEVICE_TAPI)
+    DEVICE_TAPI_WITH_CONNECT_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_CONNECT_RULES)
+    device_client.AddDevice(Device(**DEVICE_TAPI_WITH_CONNECT_RULES))
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver: _Driver = driver_instance_cache.get(DEVICE_TAPI_UUID)
+    assert driver is not None
+
+
+def test_device_tapi_get(
+    context_client: ContextClient,      # pylint: disable=redefined-outer-name
+    device_client: DeviceClient):       # pylint: disable=redefined-outer-name
+
+    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
+
+    initial_config = device_client.GetInitialConfig(DeviceId(**DEVICE_TAPI_ID))
+    LOGGER.info('initial_config = {:s}'.format(grpc_message_to_json_string(initial_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_TAPI_ID))
+    LOGGER.info('device_data = {:s}'.format(grpc_message_to_json_string(device_data)))
+
+
+def test_device_tapi_configure(
+    context_client: ContextClient,      # pylint: disable=redefined-outer-name
+    device_client: DeviceClient,        # pylint: disable=redefined-outer-name
+    device_service: DeviceService):     # pylint: disable=redefined-outer-name
+
+    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_TAPI_UUID)
+    assert driver is not None
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    DEVICE_TAPI_WITH_CONFIG_RULES = copy.deepcopy(DEVICE_TAPI)
+    DEVICE_TAPI_WITH_CONFIG_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_CONFIG_RULES)
+    device_client.ConfigureDevice(Device(**DEVICE_TAPI_WITH_CONFIG_RULES))
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_TAPI_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+    for config_rule in DEVICE_TAPI_CONFIG_RULES:
+        config_rule = (
+            ConfigActionEnum.Name(config_rule['action']), config_rule['resource_key'], config_rule['resource_value'])
+        assert config_rule in config_rules
+
+
+def test_device_tapi_deconfigure(
+    context_client: ContextClient,      # pylint: disable=redefined-outer-name
+    device_client: DeviceClient,        # pylint: disable=redefined-outer-name
+    device_service: DeviceService):     # pylint: disable=redefined-outer-name
+
+    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
+
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver: _Driver = driver_instance_cache.get(DEVICE_TAPI_UUID)
+    assert driver is not None
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    DEVICE_TAPI_WITH_DECONFIG_RULES = copy.deepcopy(DEVICE_TAPI)
+    DEVICE_TAPI_WITH_DECONFIG_RULES['device_config']['config_rules'].extend(DEVICE_TAPI_DECONFIG_RULES)
+    device_client.ConfigureDevice(Device(**DEVICE_TAPI_WITH_DECONFIG_RULES))
+
+    # Requires to retrieve data from device; might be slow. Uncomment only when needed and test does not pass directly.
+    #driver_config = sorted(driver.GetConfig(), key=operator.itemgetter(0))
+    #LOGGER.info('driver_config = {:s}'.format(str(driver_config)))
+
+    device_data = context_client.GetDevice(DeviceId(**DEVICE_TAPI_ID))
+    config_rules = [
+        (ConfigActionEnum.Name(config_rule.action), config_rule.resource_key, config_rule.resource_value)
+        for config_rule in device_data.device_config.config_rules
+    ]
+    LOGGER.info('device_data.device_config.config_rules = \n{:s}'.format(
+        '\n'.join(['{:s} {:s} = {:s}'.format(*config_rule) for config_rule in config_rules])))
+    for config_rule in DEVICE_TAPI_DECONFIG_RULES:
+        action_set = ConfigActionEnum.Name(ConfigActionEnum.CONFIGACTION_SET)
+        config_rule = (action_set, config_rule['resource_key'], config_rule['resource_value'])
+        assert config_rule not in config_rules
+
+
+def test_device_tapi_delete(
+    device_client : DeviceClient,       # pylint: disable=redefined-outer-name
+    device_service : DeviceService):    # pylint: disable=redefined-outer-name
+
+    if not ENABLE_TAPI: pytest.skip('Skipping test: No TAPI device has been configured')
+
+    device_client.DeleteDevice(DeviceId(**DEVICE_TAPI_ID))
+    driver_instance_cache = device_service.device_servicer.driver_instance_cache
+    driver : _Driver = driver_instance_cache.get(DEVICE_TAPI_UUID, {})
+    assert driver is None
-- 
GitLab


From 810d16cfb5ed06ad4fd8f573350b78e915768934 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 16:34:27 +0200
Subject: [PATCH 26/60] Service component: - Migrated to use new generic gRPC
 servicer - Migrated to use new generic Rest servicer - Migrated to use new
 settings framework - Migrated tests to use new generic servicers and mock's -
 Extracted common unitary test functionalities into separate code files -
 Minor code styling/formatting

---
 src/service/Config.py                         | 19 -----
 src/service/client/ServiceClient.py           | 10 ++-
 src/service/service/ServiceService.py         | 70 +++--------------
 .../service/ServiceServiceServicerImpl.py     |  9 +--
 src/service/service/__main__.py               | 46 +++--------
 src/service/tests/MockService_Dependencies.py | 49 ++++++++++++
 src/service/tests/PrepareTestScenario.py      | 68 ++++++++++++++++
 src/service/tests/test_unitary.py             | 77 +------------------
 8 files changed, 153 insertions(+), 195 deletions(-)
 create mode 100644 src/service/tests/MockService_Dependencies.py
 create mode 100644 src/service/tests/PrepareTestScenario.py

diff --git a/src/service/Config.py b/src/service/Config.py
index 5d551b023..70a332512 100644
--- a/src/service/Config.py
+++ b/src/service/Config.py
@@ -12,22 +12,3 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging
-
-# General settings
-LOG_LEVEL = logging.WARNING
-
-# gRPC settings
-GRPC_SERVICE_PORT = 3030
-GRPC_MAX_WORKERS  = 10
-GRPC_GRACE_PERIOD = 60
-
-# Prometheus settings
-METRICS_PORT = 9192
-
-# Dependency micro-service connection settings
-CONTEXT_SERVICE_HOST = '127.0.0.1'
-CONTEXT_SERVICE_PORT = 1010
-
-DEVICE_SERVICE_HOST = '127.0.0.1'
-DEVICE_SERVICE_PORT = 2020
diff --git a/src/service/client/ServiceClient.py b/src/service/client/ServiceClient.py
index a44842768..a6335bfce 100644
--- a/src/service/client/ServiceClient.py
+++ b/src/service/client/ServiceClient.py
@@ -13,6 +13,8 @@
 # limitations under the License.
 
 import grpc, logging
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_grpc
 from common.tools.client.RetryDecorator import retry, delay_exponential
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from service.proto.context_pb2 import Empty, Service, ServiceId
@@ -24,9 +26,11 @@ DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
 RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
 
 class ServiceClient:
-    def __init__(self, address, port):
-        self.endpoint = '{:s}:{:s}'.format(str(address), str(port))
-        LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint))
+    def __init__(self, host=None, port=None):
+        if not host: host = get_service_host(ServiceNameEnum.SERVICE)
+        if not port: port = get_service_port_grpc(ServiceNameEnum.SERVICE)
+        self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
+        LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint)))
         self.channel = None
         self.stub = None
         self.connect()
diff --git a/src/service/service/ServiceService.py b/src/service/service/ServiceService.py
index 21945b7d3..356c314c3 100644
--- a/src/service/service/ServiceService.py
+++ b/src/service/service/ServiceService.py
@@ -12,72 +12,22 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import grpc, logging
-from concurrent import futures
-from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
-from grpc_health.v1.health_pb2 import HealthCheckResponse
-from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_port_grpc
 from common.orm.backend.BackendEnum import BackendEnum
 from common.orm.Database import Database
 from common.orm.Factory import get_database_backend
-from context.client.ContextClient import ContextClient
-from device.client.DeviceClient import DeviceClient
-from service.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+from common.tools.service.GenericGrpcService import GenericGrpcService
 from service.proto.service_pb2_grpc import add_ServiceServiceServicer_to_server
 from .ServiceServiceServicerImpl import ServiceServiceServicerImpl
 from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
 
-BIND_ADDRESS = '0.0.0.0'
-LOGGER = logging.getLogger(__name__)
+class ServiceService(GenericGrpcService):
+    def __init__(self, service_handler_factory : ServiceHandlerFactory, cls_name: str = __name__) -> None:
+        port = get_service_port_grpc(ServiceNameEnum.SERVICE)
+        super().__init__(port, cls_name=cls_name)
+        database = Database(get_database_backend(backend=BackendEnum.INMEMORY))
+        self.service_servicer = ServiceServiceServicerImpl(database, service_handler_factory)
 
-class ServiceService:
-    def __init__(
-        self, context_client : ContextClient, device_client : DeviceClient,
-        service_handler_factory : ServiceHandlerFactory,
-        address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS,
-        grace_period=GRPC_GRACE_PERIOD):
-
-        self.context_client = context_client
-        self.device_client = device_client
-        self.service_handler_factory = service_handler_factory
-        self.address = address
-        self.port = port
-        self.endpoint = None
-        self.max_workers = max_workers
-        self.grace_period = grace_period
-        self.service_servicer = None
-        self.health_servicer = None
-        self.pool = None
-        self.server = None
-
-        self.database = Database(get_database_backend(backend=BackendEnum.INMEMORY))
-
-    def start(self):
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
-        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
-            str(self.endpoint), str(self.max_workers)))
-
-        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
-        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
-
-        self.service_servicer = ServiceServiceServicerImpl(
-            self.context_client, self.device_client, self.database, self.service_handler_factory)
+    def install_servicers(self):
         add_ServiceServiceServicer_to_server(self.service_servicer, self.server)
-
-        self.health_servicer = HealthServicer(
-            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
-        add_HealthServicer_to_server(self.health_servicer, self.server)
-
-        port = self.server.add_insecure_port(self.endpoint)
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
-        LOGGER.info('Listening on {:s}...'.format(str(self.endpoint)))
-        self.server.start()
-        self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
-
-        LOGGER.debug('Service started')
-
-    def stop(self):
-        LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
-        self.health_servicer.enter_graceful_shutdown()
-        self.server.stop(self.grace_period)
-        LOGGER.debug('Service stopped')
diff --git a/src/service/service/ServiceServiceServicerImpl.py b/src/service/service/ServiceServiceServicerImpl.py
index 772069932..f34b99d63 100644
--- a/src/service/service/ServiceServiceServicerImpl.py
+++ b/src/service/service/ServiceServiceServicerImpl.py
@@ -39,13 +39,10 @@ METHOD_NAMES = ['CreateService', 'UpdateService', 'DeleteService']
 METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
 
 class ServiceServiceServicerImpl(ServiceServiceServicer):
-    def __init__(
-        self, context_client : ContextClient, device_client : DeviceClient, database : Database,
-        service_handler_factory : ServiceHandlerFactory):
-
+    def __init__(self, database : Database, service_handler_factory : ServiceHandlerFactory) -> None:
         LOGGER.debug('Creating Servicer...')
-        self.context_client = context_client
-        self.device_client = device_client
+        self.context_client = ContextClient()
+        self.device_client = DeviceClient()
         self.database = database
         self.service_handler_factory = service_handler_factory
         LOGGER.debug('Servicer Created')
diff --git a/src/service/service/__main__.py b/src/service/service/__main__.py
index cc1b00895..1a67a309f 100644
--- a/src/service/service/__main__.py
+++ b/src/service/service/__main__.py
@@ -14,12 +14,10 @@
 
 import logging, signal, sys, threading
 from prometheus_client import start_http_server
-from common.Settings import get_setting, wait_for_environment_variables
-from context.client.ContextClient import ContextClient
-from device.client.DeviceClient import DeviceClient
-from service.Config import (
-    CONTEXT_SERVICE_HOST, CONTEXT_SERVICE_PORT, DEVICE_SERVICE_HOST, DEVICE_SERVICE_PORT, GRPC_SERVICE_PORT,
-    GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT)
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
+    wait_for_environment_variables)
 from .ServiceService import ServiceService
 from .service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
 from .service_handlers import SERVICE_HANDLERS
@@ -34,51 +32,31 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
 def main():
     global LOGGER # pylint: disable=global-statement
 
-    grpc_service_port    = get_setting('SERVICESERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT   )
-    max_workers          = get_setting('MAX_WORKERS',                      default=GRPC_MAX_WORKERS    )
-    grace_period         = get_setting('GRACE_PERIOD',                     default=GRPC_GRACE_PERIOD   )
-    log_level            = get_setting('LOG_LEVEL',                        default=LOG_LEVEL           )
-    metrics_port         = get_setting('METRICS_PORT',                     default=METRICS_PORT        )
-
+    log_level = get_log_level()
     logging.basicConfig(level=log_level)
     LOGGER = logging.getLogger(__name__)
 
     wait_for_environment_variables([
-        'CONTEXTSERVICE_SERVICE_HOST', 'CONTEXTSERVICE_SERVICE_PORT_GRPC',
-        'DEVICESERVICE_SERVICE_HOST', 'DEVICESERVICE_SERVICE_PORT_GRPC'
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
+        get_env_var_name(ServiceNameEnum.DEVICE,  ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.DEVICE,  ENVVAR_SUFIX_SERVICE_PORT_GRPC),
     ])
 
-    context_service_host = get_setting('CONTEXTSERVICE_SERVICE_HOST',      default=CONTEXT_SERVICE_HOST)
-    context_service_port = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC', default=CONTEXT_SERVICE_PORT)
-    device_service_host  = get_setting('DEVICESERVICE_SERVICE_HOST',       default=DEVICE_SERVICE_HOST )
-    device_service_port  = get_setting('DEVICESERVICE_SERVICE_PORT_GRPC',  default=DEVICE_SERVICE_PORT )
-
     signal.signal(signal.SIGINT,  signal_handler)
     signal.signal(signal.SIGTERM, signal_handler)
 
     LOGGER.info('Starting...')
 
     # Start metrics server
+    metrics_port = get_metrics_port()
     start_http_server(metrics_port)
 
-    # Initialize Context Client
-    if context_service_host is None or context_service_port is None:
-        raise Exception('Wrong address({:s}):port({:s}) of Context component'.format(
-            str(context_service_host), str(context_service_port)))
-    context_client = ContextClient(context_service_host, context_service_port)
-
-    # Initialize Device Client
-    if device_service_host is None or device_service_port is None:
-        raise Exception('Wrong address({:s}):port({:s}) of Device component'.format(
-            str(device_service_host), str(device_service_port)))
-    device_client = DeviceClient(device_service_host, device_service_port)
-
+    # Initialize ServiceHandler Factory
     service_handler_factory = ServiceHandlerFactory(SERVICE_HANDLERS)
 
     # Starting service service
-    grpc_service = ServiceService(
-        context_client, device_client, service_handler_factory, port=grpc_service_port, max_workers=max_workers,
-        grace_period=grace_period)
+    grpc_service = ServiceService(service_handler_factory)
     grpc_service.start()
 
     # Wait for Ctrl+C or termination signal
diff --git a/src/service/tests/MockService_Dependencies.py b/src/service/tests/MockService_Dependencies.py
new file mode 100644
index 000000000..8194ba943
--- /dev/null
+++ b/src/service/tests/MockService_Dependencies.py
@@ -0,0 +1,49 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from typing import Union
+from common.Constants import ServiceNameEnum
+from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name
+from common.tests.MockServicerImpl_Context import MockServicerImpl_Context
+from common.tests.MockServicerImpl_Device import MockServicerImpl_Device
+from common.tools.service.GenericGrpcService import GenericGrpcService
+from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server
+from device.proto.device_pb2_grpc import add_DeviceServiceServicer_to_server
+
+LOCAL_HOST = '127.0.0.1'
+
+SERVICE_CONTEXT = ServiceNameEnum.CONTEXT
+SERVICE_DEVICE = ServiceNameEnum.DEVICE
+
+class MockService_Dependencies(GenericGrpcService):
+    # Mock Service implementing Context and Device to simplify unitary tests of Device
+
+    def __init__(self, bind_port: Union[str, int]) -> None:
+        super().__init__(bind_port, LOCAL_HOST, enable_health_servicer=False, cls_name='MockService')
+
+    # pylint: disable=attribute-defined-outside-init
+    def install_servicers(self):
+        self.context_servicer = MockServicerImpl_Context()
+        add_ContextServiceServicer_to_server(self.context_servicer, self.server)
+
+        self.device_servicer = MockServicerImpl_Device()
+        add_DeviceServiceServicer_to_server(self.device_servicer, self.server)
+
+    def configure_env_vars(self):
+        os.environ[get_env_var_name(SERVICE_CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     )] = str(self.bind_address)
+        os.environ[get_env_var_name(SERVICE_CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(self.bind_port)
+
+        os.environ[get_env_var_name(SERVICE_DEVICE, ENVVAR_SUFIX_SERVICE_HOST     )] = str(self.bind_address)
+        os.environ[get_env_var_name(SERVICE_DEVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(self.bind_port)
diff --git a/src/service/tests/PrepareTestScenario.py b/src/service/tests/PrepareTestScenario.py
new file mode 100644
index 000000000..bcf3cd156
--- /dev/null
+++ b/src/service/tests/PrepareTestScenario.py
@@ -0,0 +1,68 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import pytest, os
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_service_port_grpc)
+from context.client.ContextClient import ContextClient
+from device.client.DeviceClient import DeviceClient
+from service.client.ServiceClient import ServiceClient
+from service.service.ServiceService import ServiceService
+from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
+from service.service.service_handlers import SERVICE_HANDLERS
+from service.tests.MockService_Dependencies import MockService_Dependencies
+
+LOCAL_HOST = '127.0.0.1'
+MOCKSERVICE_PORT = 10000
+SERVICE_SERVICE_PORT = MOCKSERVICE_PORT + get_service_port_grpc(ServiceNameEnum.SERVICE) # avoid privileged ports
+os.environ[get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
+os.environ[get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(SERVICE_SERVICE_PORT)
+
+@pytest.fixture(scope='session')
+def mock_service():
+    _service = MockService_Dependencies(MOCKSERVICE_PORT)
+    _service.configure_env_vars()
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def context_client(mock_service : MockService_Dependencies): # pylint: disable=redefined-outer-name
+    _client = ContextClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def device_client(mock_service : MockService_Dependencies): # pylint: disable=redefined-outer-name
+    _client = DeviceClient()
+    yield _client
+    _client.close()
+
+@pytest.fixture(scope='session')
+def service_service(
+    context_client : ContextClient, # pylint: disable=redefined-outer-name
+    device_client : DeviceClient):  # pylint: disable=redefined-outer-name
+
+    _service_handler_factory = ServiceHandlerFactory(SERVICE_HANDLERS)
+    _service = ServiceService(_service_handler_factory)
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def service_client(service_service : ServiceService): # pylint: disable=redefined-outer-name
+    _client = ServiceClient()
+    yield _client
+    _client.close()
diff --git a/src/service/tests/test_unitary.py b/src/service/tests/test_unitary.py
index 812a65c5c..60fd17371 100644
--- a/src/service/tests/test_unitary.py
+++ b/src/service/tests/test_unitary.py
@@ -12,90 +12,21 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import copy, grpc, logging, os, pytest
-from common.tests.MockService import MockService
-from common.tests.MockServicerImpl_Context import MockServicerImpl_Context
-from common.tests.MockServicerImpl_Device import MockServicerImpl_Device
+import copy, grpc, logging, pytest
 from common.tests.PytestGenerateTests import pytest_generate_tests # (required) pylint: disable=unused-import
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
 from context.proto.context_pb2 import Context, ContextId, DeviceId, Link, LinkId, Topology, Device, TopologyId
-from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server
 from device.client.DeviceClient import DeviceClient
-from device.proto.device_pb2_grpc import add_DeviceServiceServicer_to_server
-from service.Config import (
-    GRPC_SERVICE_PORT as SERVICE_GRPC_SERVICE_PORT, GRPC_MAX_WORKERS as SERVICE_GRPC_MAX_WORKERS,
-    GRPC_GRACE_PERIOD as SERVICE_GRPC_GRACE_PERIOD)
 from service.client.ServiceClient import ServiceClient
 from service.proto.context_pb2 import Service, ServiceId
-from service.service.ServiceService import ServiceService
-from service.service.service_handler_api.ServiceHandlerFactory import ServiceHandlerFactory
-from service.service.service_handlers import SERVICE_HANDLERS
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    mock_service, service_service, context_client, device_client, service_client)
 
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
 
-SERVICE_GRPC_SERVICE_PORT = 10000 + SERVICE_GRPC_SERVICE_PORT # avoid privileged ports
-
-LOCALHOST = '127.0.0.1'
-MOCKSERVER_GRPC_PORT = 10000
-
-class MockService_Combined(MockService):
-    # Mock Server implementing Context and Service to simplify unitary tests of Compute
-
-    def __init__(self, cls_name='MockService_Service'):
-        super().__init__(LOCALHOST, MOCKSERVER_GRPC_PORT, cls_name=cls_name)
-
-    # pylint: disable=attribute-defined-outside-init
-    def install_servicers(self):
-        self.context_servicer = MockServicerImpl_Context()
-        add_ContextServiceServicer_to_server(self.context_servicer, self.server)
-        self.device_servicer = MockServicerImpl_Device()
-        add_DeviceServiceServicer_to_server(self.device_servicer, self.server)
-
-os.environ['CONTEXTSERVICE_SERVICE_HOST'] = LOCALHOST
-os.environ['CONTEXTSERVICE_SERVICE_PORT_GRPC'] = str(MOCKSERVER_GRPC_PORT)
-os.environ['DEVICESERVICE_SERVICE_HOST'] = LOCALHOST
-os.environ['DEVICESERVICE_SERVICE_PORT_GRPC'] = str(MOCKSERVER_GRPC_PORT)
-
-@pytest.fixture(scope='session')
-def mockservice():
-    _service = MockService_Combined()
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def context_client(mockservice : MockService_Combined): # pylint: disable=redefined-outer-name
-    _client = ContextClient(address=LOCALHOST, port=MOCKSERVER_GRPC_PORT)
-    yield _client
-    _client.close()
-
-@pytest.fixture(scope='session')
-def device_client(mockservice : MockService_Combined): # pylint: disable=redefined-outer-name
-    _client = DeviceClient(address=LOCALHOST, port=MOCKSERVER_GRPC_PORT)
-    yield _client
-    _client.close()
-
-@pytest.fixture(scope='session')
-def service_service(
-    context_client : ContextClient, # pylint: disable=redefined-outer-name
-    device_client : DeviceClient):  # pylint: disable=redefined-outer-name
-
-    _service_handler_factory = ServiceHandlerFactory(SERVICE_HANDLERS)
-    _service = ServiceService(
-        context_client, device_client, _service_handler_factory,
-        port=SERVICE_GRPC_SERVICE_PORT, max_workers=SERVICE_GRPC_MAX_WORKERS, grace_period=SERVICE_GRPC_GRACE_PERIOD)
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def service_client(service_service : ServiceService): # pylint: disable=redefined-outer-name
-    _client = ServiceClient(address=LOCALHOST, port=SERVICE_GRPC_SERVICE_PORT)
-    yield _client
-    _client.close()
-
 try:
     from .ServiceHandlersToTest import SERVICE_HANDLERS_TO_TEST
 except ImportError:
-- 
GitLab


From 38659ca6bb4cffcc3876fe0bab6cffdc761182af Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 16:36:51 +0200
Subject: [PATCH 27/60] Slice component: - Migrated to use new generic gRPC
 servicer - Migrated to use new settings framework

---
 src/slice/Config.py                           | 34 ++++------
 src/slice/client/SliceClient.py               |  8 ++-
 src/slice/service/SliceService.py             | 66 +++----------------
 src/slice/service/SliceServiceServicerImpl.py | 34 +++++-----
 src/slice/service/__main__.py                 | 54 +++------------
 5 files changed, 54 insertions(+), 142 deletions(-)

diff --git a/src/slice/Config.py b/src/slice/Config.py
index e6d770d00..70a332512 100644
--- a/src/slice/Config.py
+++ b/src/slice/Config.py
@@ -1,22 +1,14 @@
-import logging
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
 
-# General settings
-LOG_LEVEL = logging.WARNING
-
-# gRPC settings
-GRPC_SERVICE_PORT = 4040
-GRPC_MAX_WORKERS  = 10
-GRPC_GRACE_PERIOD = 60
-
-# Prometheus settings
-METRICS_PORT = 9192
-
-# Dependency micro-service connection settings
-CONTEXT_SERVICE_HOST = '127.0.0.1'
-CONTEXT_SERVICE_PORT = 1010
-
-SERVICE_SERVICE_HOST = '127.0.0.1'
-SERVICE_SERVICE_PORT = 3030
-
-INTERDOMAIN_SERVICE_HOST = '127.0.0.1'
-INTERDOMAIN_SERVICE_PORT = 10010
diff --git a/src/slice/client/SliceClient.py b/src/slice/client/SliceClient.py
index 5566108f8..d1783e882 100644
--- a/src/slice/client/SliceClient.py
+++ b/src/slice/client/SliceClient.py
@@ -13,6 +13,8 @@
 # limitations under the License.
 
 import grpc, logging
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_grpc
 from common.tools.client.RetryDecorator import retry, delay_exponential
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from slice.proto.context_pb2 import Empty, Slice, SliceId
@@ -24,8 +26,10 @@ DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
 RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
 
 class SliceClient:
-    def __init__(self, address, port):
-        self.endpoint = '{:s}:{:s}'.format(str(address), str(port))
+    def __init__(self, host=None, port=None):
+        if not host: host = get_service_host(ServiceNameEnum.SLICE)
+        if not port: port = get_service_port_grpc(ServiceNameEnum.SLICE)
+        self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
         LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint))
         self.channel = None
         self.stub = None
diff --git a/src/slice/service/SliceService.py b/src/slice/service/SliceService.py
index a7ad26946..7121ae467 100644
--- a/src/slice/service/SliceService.py
+++ b/src/slice/service/SliceService.py
@@ -12,65 +12,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import grpc, logging
-from concurrent import futures
-from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
-from grpc_health.v1.health_pb2 import HealthCheckResponse
-from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
-from context.client.ContextClient import ContextClient
-from interdomain.client.InterdomainClient import InterdomainClient
-from service.client.ServiceClient import ServiceClient
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_port_grpc
+from common.tools.service.GenericGrpcService import GenericGrpcService
 from slice.proto.slice_pb2_grpc import add_SliceServiceServicer_to_server
 from slice.service.SliceServiceServicerImpl import SliceServiceServicerImpl
-from slice.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
 
-BIND_ADDRESS = '0.0.0.0'
-LOGGER = logging.getLogger(__name__)
+class SliceService(GenericGrpcService):
+    def __init__(self, cls_name: str = __name__) -> None:
+        port = get_service_port_grpc(ServiceNameEnum.SLICE)
+        super().__init__(port, cls_name=cls_name)
+        self.slice_servicer = SliceServiceServicerImpl()
 
-class SliceService:
-    def __init__(
-        self, context_client : ContextClient, interdomain_client : InterdomainClient, service_client : ServiceClient,
-        address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD):
-
-        self.context_client = context_client
-        self.interdomain_client = interdomain_client
-        self.service_client = service_client
-        self.address = address
-        self.port = port
-        self.endpoint = None
-        self.max_workers = max_workers
-        self.grace_period = grace_period
-        self.slice_servicer = None
-        self.health_servicer = None
-        self.pool = None
-        self.server = None
-
-    def start(self):
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
-        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
-            str(self.endpoint), str(self.max_workers)))
-
-        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
-        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
-
-        self.slice_servicer = SliceServiceServicerImpl(
-            self.context_client, self.interdomain_client, self.service_client)
+    def install_servicers(self):
         add_SliceServiceServicer_to_server(self.slice_servicer, self.server)
-
-        self.health_servicer = HealthServicer(
-            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
-        add_HealthServicer_to_server(self.health_servicer, self.server)
-
-        port = self.server.add_insecure_port(self.endpoint)
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
-        LOGGER.info('Listening on {:s}...'.format(str(self.endpoint)))
-        self.server.start()
-        self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
-
-        LOGGER.debug('Service started')
-
-    def stop(self):
-        LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
-        self.health_servicer.enter_graceful_shutdown()
-        self.server.stop(self.grace_period)
-        LOGGER.debug('Service stopped')
diff --git a/src/slice/service/SliceServiceServicerImpl.py b/src/slice/service/SliceServiceServicerImpl.py
index bd26d1943..eae452400 100644
--- a/src/slice/service/SliceServiceServicerImpl.py
+++ b/src/slice/service/SliceServiceServicerImpl.py
@@ -28,17 +28,14 @@ METHOD_NAMES = ['CreateSlice', 'UpdateSlice', 'DeleteSlice']
 METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
 
 class SliceServiceServicerImpl(SliceServiceServicer):
-    def __init__(
-        self, context_client : ContextClient, interdomain_client : InterdomainClient, service_client : ServiceClient
-    ):
+    def __init__(self):
         LOGGER.debug('Creating Servicer...')
-        self.context_client = context_client
-        self.interdomain_client = interdomain_client
-        self.service_client = service_client
         LOGGER.debug('Servicer Created')
 
     def create_update(self, request : Slice) -> SliceId:
-        slice_id = self.context_client.SetSlice(request)
+        context_client = ContextClient()
+
+        slice_id = context_client.SetSlice(request)
         if len(request.slice_endpoint_ids) != 2: return slice_id
 
         domains = set()
@@ -48,7 +45,8 @@ class SliceServiceServicerImpl(SliceServiceServicer):
 
         is_multi_domain = len(domains) == 2
         if is_multi_domain:
-            slice_id = self.interdomain_client.RequestSlice(request)
+            interdomain_client = InterdomainClient()
+            slice_id = interdomain_client.RequestSlice(request)
         else:
             # pylint: disable=no-member
             service_request = Service()
@@ -57,7 +55,8 @@ class SliceServiceServicerImpl(SliceServiceServicer):
             service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
             service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
 
-            service_reply = self.service_client.CreateService(service_request)
+            service_client = ServiceClient()
+            service_reply = service_client.CreateService(service_request)
             if service_reply != service_request.service_id: # pylint: disable=no-member
                 raise Exception('Service creation failed. Wrong Service Id was returned')
 
@@ -84,7 +83,7 @@ class SliceServiceServicerImpl(SliceServiceServicer):
                      'address_ip': '0.0.0.0', 'address_prefix': 0},
                     sort_keys=True)
 
-            service_reply = self.service_client.UpdateService(service_request)
+            service_reply = service_client.UpdateService(service_request)
             if service_reply != service_request.service_id: # pylint: disable=no-member
                 raise Exception('Service update failed. Wrong Service Id was returned')
 
@@ -92,29 +91,29 @@ class SliceServiceServicerImpl(SliceServiceServicer):
             reply.CopyFrom(request)
             slice_service_id = reply.slice_service_ids.add()
             slice_service_id.CopyFrom(service_reply)
-            self.context_client.SetSlice(reply)
+            context_client.SetSlice(reply)
             slice_id = reply.slice_id
 
-        slice_ = self.context_client.GetSlice(slice_id)
+        slice_ = context_client.GetSlice(slice_id)
         slice_active = Slice()
         slice_active.CopyFrom(slice_)
         slice_active.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_ACTIVE
-        self.context_client.SetSlice(slice_active)
+        context_client.SetSlice(slice_active)
         return slice_id
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def CreateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
         #try:
-        #    slice_ = self.context_client.GetSlice(request.slice_id)
+        #    slice_ = context_client.GetSlice(request.slice_id)
         #    slice_id = slice_.slice_id
         #except grpc.RpcError:
-        #    slice_id = self.context_client.SetSlice(request)
+        #    slice_id = context_client.SetSlice(request)
         #return slice_id
         return self.create_update(request)
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def UpdateSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
-        #slice_id = self.context_client.SetSlice(request)
+        #slice_id = context_client.SetSlice(request)
         #if len(request.slice_endpoint_ids) != 2: return slice_id
         #
         #domains = set()
@@ -124,7 +123,8 @@ class SliceServiceServicerImpl(SliceServiceServicer):
         #
         #is_multi_domain = len(domains) == 2
         #if is_multi_domain:
-        #    return self.interdomain_client.LookUpSlice(request)
+        #    interdomain_client = InterdomainClient()
+        #    return interdomain_client.LookUpSlice(request)
         #else:
         #    raise NotImplementedError('Slice should create local services for single domain slice')
         return self.create_update(request)
diff --git a/src/slice/service/__main__.py b/src/slice/service/__main__.py
index 76bb5fa34..f77d86bff 100644
--- a/src/slice/service/__main__.py
+++ b/src/slice/service/__main__.py
@@ -14,14 +14,8 @@
 
 import logging, signal, sys, threading
 from prometheus_client import start_http_server
-from common.Settings import get_setting, wait_for_environment_variables
-from context.client.ContextClient import ContextClient
-from interdomain.client.InterdomainClient import InterdomainClient
-from service.client.ServiceClient import ServiceClient
-from slice.Config import (
-    CONTEXT_SERVICE_HOST, CONTEXT_SERVICE_PORT, GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD,
-    INTERDOMAIN_SERVICE_HOST, INTERDOMAIN_SERVICE_PORT, LOG_LEVEL, METRICS_PORT, SERVICE_SERVICE_HOST,
-    SERVICE_SERVICE_PORT)
+from common.Constants import ServiceNameEnum
+from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port, wait_for_environment_variables
 from .SliceService import SliceService
 
 terminate = threading.Event()
@@ -34,58 +28,28 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
 def main():
     global LOGGER # pylint: disable=global-statement
 
-    grpc_service_port        = get_setting('SLICESERVICE_SERVICE_PORT_GRPC',       default=GRPC_SERVICE_PORT       )
-    max_workers              = get_setting('MAX_WORKERS',                          default=GRPC_MAX_WORKERS        )
-    grace_period             = get_setting('GRACE_PERIOD',                         default=GRPC_GRACE_PERIOD       )
-    log_level                = get_setting('LOG_LEVEL',                            default=LOG_LEVEL               )
-    metrics_port             = get_setting('METRICS_PORT',                         default=METRICS_PORT            )
-
+    log_level = get_log_level()
     logging.basicConfig(level=log_level)
     LOGGER = logging.getLogger(__name__)
 
     wait_for_environment_variables([
-        'CONTEXTSERVICE_SERVICE_HOST', 'CONTEXTSERVICE_SERVICE_PORT_GRPC',
-        'INTERDOMAINSERVICE_SERVICE_HOST', 'INTERDOMAINSERVICE_SERVICE_PORT_GRPC',
-        'SERVICESERVICE_SERVICE_HOST', 'SERVICESERVICE_SERVICE_PORT_GRPC',
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
+        get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.SERVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
     ])
 
-    context_service_host     = get_setting('CONTEXTSERVICE_SERVICE_HOST',          default=CONTEXT_SERVICE_HOST    )
-    context_service_port     = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC',     default=CONTEXT_SERVICE_PORT    )
-    interdomain_service_host = get_setting('INTERDOMAINSERVICE_SERVICE_HOST',      default=INTERDOMAIN_SERVICE_HOST)
-    interdomain_service_port = get_setting('INTERDOMAINSERVICE_SERVICE_PORT_GRPC', default=INTERDOMAIN_SERVICE_PORT)
-    service_service_host     = get_setting('SERVICESERVICE_SERVICE_HOST',          default=SERVICE_SERVICE_HOST    )
-    service_service_port     = get_setting('SERVICESERVICE_SERVICE_PORT_GRPC',     default=SERVICE_SERVICE_PORT    )
-
     signal.signal(signal.SIGINT,  signal_handler)
     signal.signal(signal.SIGTERM, signal_handler)
 
     LOGGER.info('Starting...')
 
     # Start metrics server
+    metrics_port = get_metrics_port()
     start_http_server(metrics_port)
 
-    # Initialize Context Client
-    if context_service_host is None or context_service_port is None:
-        raise Exception('Wrong address({:s}):port({:s}) of Context component'.format(
-            str(context_service_host), str(context_service_port)))
-    context_client = ContextClient(context_service_host, context_service_port)
-
-    # Initialize Interdomain Client
-    if interdomain_service_host is None or interdomain_service_port is None:
-        raise Exception('Wrong address({:s}):port({:s}) of Interdomain component'.format(
-            str(interdomain_service_host), str(interdomain_service_port)))
-    interdomain_client = InterdomainClient(interdomain_service_host, interdomain_service_port)
-
-    # Initialize Service Client
-    if service_service_host is None or service_service_port is None:
-        raise Exception('Wrong address({:s}):port({:s}) of Service component'.format(
-            str(service_service_host), str(service_service_port)))
-    service_client = ServiceClient(service_service_host, service_service_port)
-
     # Starting slice service
-    grpc_service = SliceService(
-        context_client, interdomain_client, service_client, port=grpc_service_port, max_workers=max_workers,
-        grace_period=grace_period)
+    grpc_service = SliceService()
     grpc_service.start()
 
     # Wait for Ctrl+C or termination signal
-- 
GitLab


From 4375de80c909326576e9908f8747e2ae328c236a Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 16:40:27 +0200
Subject: [PATCH 28/60] Compute component: - Migrated to use new generic gRPC
 servicer - Migrated to use new generic Rest servicer - Migrated to use new
 settings framework - Minor code formatting/styling

---
 src/compute/Config.py                         | 16 +-----
 src/compute/client/ComputeClient.py           | 39 +++++++------
 src/compute/service/ComputeService.py         | 57 +++----------------
 src/compute/service/__main__.py               | 26 ++++-----
 src/compute/service/rest_server/RestServer.py | 51 +++--------------
 5 files changed, 51 insertions(+), 138 deletions(-)

diff --git a/src/compute/Config.py b/src/compute/Config.py
index c568be447..341ae77f5 100644
--- a/src/compute/Config.py
+++ b/src/compute/Config.py
@@ -12,23 +12,9 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging
 from werkzeug.security import generate_password_hash
 
-# General settings
-LOG_LEVEL = logging.WARNING
-
-# gRPC settings
-GRPC_SERVICE_PORT = 9090
-GRPC_MAX_WORKERS  = 10
-GRPC_GRACE_PERIOD = 60
-
-# REST-API settings
-RESTAPI_SERVICE_PORT = 8080
-RESTAPI_BASE_URL = '/restconf/data'
+# REST-API users
 RESTAPI_USERS = {   # TODO: implement a database of credentials and permissions
     'admin': generate_password_hash('admin'),
 }
-
-# Prometheus settings
-METRICS_PORT = 9192
diff --git a/src/compute/client/ComputeClient.py b/src/compute/client/ComputeClient.py
index ac8550029..5c2cfa8b6 100644
--- a/src/compute/client/ComputeClient.py
+++ b/src/compute/client/ComputeClient.py
@@ -13,7 +13,10 @@
 # limitations under the License.
 
 import grpc, logging
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_grpc
 from common.tools.client.RetryDecorator import retry, delay_exponential
+from common.tools.grpc.Tools import grpc_message_to_json_string
 from compute.proto.compute_pb2_grpc import ComputeServiceStub
 from compute.proto.context_pb2 import (
     AuthenticationResult, Empty, Service, ServiceId, ServiceIdList, ServiceStatus, TeraFlowController)
@@ -24,8 +27,10 @@ DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
 RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
 
 class ComputeClient:
-    def __init__(self, address, port):
-        self.endpoint = '{:s}:{:s}'.format(str(address), str(port))
+    def __init__(self, host=None, port=None):
+        if not host: host = get_service_host(ServiceNameEnum.COMPUTE)
+        if not port: port = get_service_port_grpc(ServiceNameEnum.COMPUTE)
+        self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
         LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint)))
         self.channel = None
         self.stub = None
@@ -37,55 +42,55 @@ class ComputeClient:
         self.stub = ComputeServiceStub(self.channel)
 
     def close(self):
-        if(self.channel is not None): self.channel.close()
+        if self.channel is not None: self.channel.close()
         self.channel = None
         self.stub = None
 
     @RETRY_DECORATOR
     def CheckCredentials(self, request : TeraFlowController) -> AuthenticationResult:
-        LOGGER.debug('CheckCredentials request: {:s}'.format(str(request)))
+        LOGGER.debug('CheckCredentials request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.CheckCredentials(request)
-        LOGGER.debug('CheckCredentials result: {:s}'.format(str(response)))
+        LOGGER.debug('CheckCredentials result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetConnectivityServiceStatus(self, request : ServiceId) -> ServiceStatus:
-        LOGGER.debug('GetConnectivityServiceStatus request: {:s}'.format(str(request)))
+        LOGGER.debug('GetConnectivityServiceStatus request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetConnectivityServiceStatus(request)
-        LOGGER.debug('GetConnectivityServiceStatus result: {:s}'.format(str(response)))
+        LOGGER.debug('GetConnectivityServiceStatus result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def CreateConnectivityService(self, request : Service) -> ServiceId:
-        LOGGER.debug('CreateConnectivityService request: {:s}'.format(str(request)))
+        LOGGER.debug('CreateConnectivityService request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.CreateConnectivityService(request)
-        LOGGER.debug('CreateConnectivityService result: {:s}'.format(str(response)))
+        LOGGER.debug('CreateConnectivityService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def EditConnectivityService(self, request : Service) -> ServiceId:
-        LOGGER.debug('EditConnectivityService request: {:s}'.format(str(request)))
+        LOGGER.debug('EditConnectivityService request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.EditConnectivityService(request)
-        LOGGER.debug('EditConnectivityService result: {:s}'.format(str(response)))
+        LOGGER.debug('EditConnectivityService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def DeleteConnectivityService(self, request : Service) -> Empty:
-        LOGGER.debug('DeleteConnectivityService request: {:s}'.format(str(request)))
+        LOGGER.debug('DeleteConnectivityService request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.DeleteConnectivityService(request)
-        LOGGER.debug('DeleteConnectivityService result: {:s}'.format(str(response)))
+        LOGGER.debug('DeleteConnectivityService result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def GetAllActiveConnectivityServices(self, request : Empty) -> ServiceIdList:
-        LOGGER.debug('GetAllActiveConnectivityServices request: {:s}'.format(str(request)))
+        LOGGER.debug('GetAllActiveConnectivityServices request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.GetAllActiveConnectivityServices(request)
-        LOGGER.debug('GetAllActiveConnectivityServices result: {:s}'.format(str(response)))
+        LOGGER.debug('GetAllActiveConnectivityServices result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
 
     @RETRY_DECORATOR
     def ClearAllConnectivityServices(self, request : Empty) -> Empty:
-        LOGGER.debug('ClearAllConnectivityServices request: {:s}'.format(str(request)))
+        LOGGER.debug('ClearAllConnectivityServices request: {:s}'.format(grpc_message_to_json_string(request)))
         response = self.stub.ClearAllConnectivityServices(request)
-        LOGGER.debug('ClearAllConnectivityServices result: {:s}'.format(str(response)))
+        LOGGER.debug('ClearAllConnectivityServices result: {:s}'.format(grpc_message_to_json_string(response)))
         return response
diff --git a/src/compute/service/ComputeService.py b/src/compute/service/ComputeService.py
index 1f523793d..f8476e102 100644
--- a/src/compute/service/ComputeService.py
+++ b/src/compute/service/ComputeService.py
@@ -12,56 +12,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import grpc, logging
-from concurrent import futures
-from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
-from grpc_health.v1.health_pb2 import HealthCheckResponse
-from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_port_grpc
+from common.tools.service.GenericGrpcService import GenericGrpcService
 from compute.proto.compute_pb2_grpc import add_ComputeServiceServicer_to_server
 from compute.service.ComputeServiceServicerImpl import ComputeServiceServicerImpl
-from compute.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
-
-BIND_ADDRESS = '0.0.0.0'
-LOGGER = logging.getLogger(__name__)
-
-class ComputeService:
-    def __init__(self, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS,
-                 grace_period=GRPC_GRACE_PERIOD):
-        self.address = address
-        self.port = port
-        self.endpoint = None
-        self.max_workers = max_workers
-        self.grace_period = grace_period
-        self.compute_servicer = None
-        self.health_servicer = None
-        self.pool = None
-        self.server = None
-
-    def start(self):
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
-        LOGGER.debug('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
-            str(self.endpoint), str(self.max_workers)))
-
-        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
-        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
 
+class ComputeService(GenericGrpcService):
+    def __init__(self, cls_name: str = __name__) -> None:
+        port = get_service_port_grpc(ServiceNameEnum.COMPUTE)
+        super().__init__(port, cls_name=cls_name)
         self.compute_servicer = ComputeServiceServicerImpl()
-        add_ComputeServiceServicer_to_server(self.compute_servicer, self.server)
 
-        self.health_servicer = HealthServicer(
-            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
-        add_HealthServicer_to_server(self.health_servicer, self.server)
-
-        port = self.server.add_insecure_port(self.endpoint)
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
-        LOGGER.info('Listening on {:s}...'.format(str(self.endpoint)))
-        self.server.start()
-        self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
-
-        LOGGER.debug('Service started')
-
-    def stop(self):
-        LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
-        self.health_servicer.enter_graceful_shutdown()
-        self.server.stop(self.grace_period)
-        LOGGER.debug('Service stopped')
+    def install_servicers(self):
+        add_ComputeServiceServicer_to_server(self.compute_servicer, self.server)
diff --git a/src/compute/service/__main__.py b/src/compute/service/__main__.py
index cf6f82410..345b2fdd6 100644
--- a/src/compute/service/__main__.py
+++ b/src/compute/service/__main__.py
@@ -14,10 +14,10 @@
 
 import logging, signal, sys, threading
 from prometheus_client import start_http_server
-from common.Settings import get_setting, wait_for_environment_variables
-from compute.Config import (
-    GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, RESTAPI_SERVICE_PORT, RESTAPI_BASE_URL,
-    METRICS_PORT)
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
+    wait_for_environment_variables)
 from .ComputeService import ComputeService
 from .rest_server.RestServer import RestServer
 from .rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn
@@ -32,20 +32,13 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
 def main():
     global LOGGER # pylint: disable=global-statement
 
-    grpc_service_port    = get_setting('COMPUTESERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT   )
-    max_workers          = get_setting('MAX_WORKERS',                      default=GRPC_MAX_WORKERS    )
-    grace_period         = get_setting('GRACE_PERIOD',                     default=GRPC_GRACE_PERIOD   )
-    log_level            = get_setting('LOG_LEVEL',                        default=LOG_LEVEL           )
-    restapi_service_port = get_setting('RESTAPI_SERVICE_PORT',             default=RESTAPI_SERVICE_PORT)
-    restapi_base_url     = get_setting('RESTAPI_BASE_URL',                 default=RESTAPI_BASE_URL    )
-    metrics_port         = get_setting('METRICS_PORT',                     default=METRICS_PORT        )
-
+    log_level = get_log_level()
     logging.basicConfig(level=log_level)
     LOGGER = logging.getLogger(__name__)
 
     wait_for_environment_variables([
-        'CONTEXTSERVICE_SERVICE_HOST', 'CONTEXTSERVICE_SERVICE_PORT_GRPC',
-        'SERVICESERVICE_SERVICE_HOST', 'SERVICESERVICE_SERVICE_PORT_GRPC'
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
     ])
 
     signal.signal(signal.SIGINT,  signal_handler)
@@ -54,13 +47,14 @@ def main():
     LOGGER.info('Starting...')
 
     # Start metrics server
+    metrics_port = get_metrics_port()
     start_http_server(metrics_port)
 
     # Starting compute service
-    grpc_service = ComputeService(port=grpc_service_port, max_workers=max_workers, grace_period=grace_period)
+    grpc_service = ComputeService()
     grpc_service.start()
 
-    rest_server = RestServer(port=restapi_service_port, base_url=restapi_base_url)
+    rest_server = RestServer()
     register_ietf_l2vpn(rest_server)
     rest_server.start()
 
diff --git a/src/compute/service/rest_server/RestServer.py b/src/compute/service/rest_server/RestServer.py
index 26055f8df..d9b6cd915 100644
--- a/src/compute/service/rest_server/RestServer.py
+++ b/src/compute/service/rest_server/RestServer.py
@@ -12,45 +12,12 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging, threading, time
-from flask import Flask, request
-from flask_restful import Api, Resource
-from werkzeug.serving import make_server
-from compute.Config import RESTAPI_BASE_URL, RESTAPI_SERVICE_PORT
-
-logging.getLogger('werkzeug').setLevel(logging.WARNING)
-
-BIND_ADDRESS = '0.0.0.0'
-LOGGER = logging.getLogger(__name__)
-
-def log_request(response):
-    timestamp = time.strftime('[%Y-%b-%d %H:%M]')
-    LOGGER.info('%s %s %s %s %s', timestamp, request.remote_addr, request.method, request.full_path, response.status)
-    return response
-
-class RestServer(threading.Thread):
-    def __init__(self, host=BIND_ADDRESS, port=RESTAPI_SERVICE_PORT, base_url=RESTAPI_BASE_URL):
-        threading.Thread.__init__(self, daemon=True)
-        self.host = host
-        self.port = port
-        self.base_url = base_url
-        self.srv = None
-        self.ctx = None
-        self.app = Flask(__name__)
-        self.app.after_request(log_request)
-        self.api = Api(self.app, prefix=self.base_url)
-
-    def add_resource(self, resource : Resource, *urls, **kwargs):
-        self.api.add_resource(resource, *urls, **kwargs)
-
-    def run(self):
-        self.srv = make_server(self.host, self.port, self.app, threaded=True)
-        self.ctx = self.app.app_context()
-        self.ctx.push()
-
-        endpoint = 'http://{:s}:{:s}{:s}'.format(str(self.host), str(self.port), str(self.base_url))
-        LOGGER.info('Listening on {:s}...'.format(str(endpoint)))
-        self.srv.serve_forever()
-
-    def shutdown(self):
-        self.srv.shutdown()
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_baseurl_http, get_service_port_http
+from common.tools.service.GenericRestServer import GenericRestServer
+
+class RestServer(GenericRestServer):
+    def __init__(self, cls_name: str = __name__) -> None:
+        bind_port = get_service_port_http(ServiceNameEnum.COMPUTE)
+        base_url = get_service_baseurl_http(ServiceNameEnum.COMPUTE)
+        super().__init__(bind_port, base_url, cls_name=cls_name)
-- 
GitLab


From eb1c97b8186bd874db0af4224fc3ba45fa0c7321 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 17:07:10 +0200
Subject: [PATCH 29/60] Compute component: - Migrated to use new generic Rest
 servicer - Moved client declarations close to use places to prevent
 initialization locks - Adaptations to comply with the new settings framework
 - Updated unitary tests to use new generic Rest and gRPC servicers and
 clients - Minor code styling/formatting

---
 .../nbi_plugins/ietf_l2vpn/L2VPN_Service.py   | 18 ++---
 .../nbi_plugins/ietf_l2vpn/L2VPN_Services.py  | 14 ++--
 .../ietf_l2vpn/L2VPN_SiteNetworkAccesses.py   | 21 +++---
 .../nbi_plugins/ietf_l2vpn/__init__.py        |  2 +-
 src/compute/tests/MockService_Dependencies.py | 58 ++++++++++++++++
 src/compute/tests/PrepareTestScenario.py      | 52 ++++++++++++++
 src/compute/tests/test_unitary.py             | 69 ++-----------------
 7 files changed, 134 insertions(+), 100 deletions(-)
 create mode 100644 src/compute/tests/MockService_Dependencies.py
 create mode 100644 src/compute/tests/PrepareTestScenario.py

diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py
index 27489410f..17ae49478 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Service.py
@@ -17,7 +17,6 @@ from flask import request
 from flask.json import jsonify
 from flask_restful import Resource
 from common.Constants import DEFAULT_CONTEXT_UUID
-from common.Settings import get_setting
 from context.client.ContextClient import ContextClient
 from context.proto.context_pb2 import ServiceId, SliceStatusEnum
 from service.client.ServiceClient import ServiceClient
@@ -29,22 +28,16 @@ from .tools.HttpStatusCodes import HTTP_GATEWAYTIMEOUT, HTTP_NOCONTENT, HTTP_OK,
 LOGGER = logging.getLogger(__name__)
 
 class L2VPN_Service(Resource):
-    def __init__(self) -> None:
-        super().__init__()
-        self.context_client = ContextClient(
-            get_setting('CONTEXTSERVICE_SERVICE_HOST'), get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC'))
-        self.service_client = ServiceClient(
-            get_setting('SERVICESERVICE_SERVICE_HOST'), get_setting('SERVICESERVICE_SERVICE_PORT_GRPC'))
-
     @HTTP_AUTH.login_required
     def get(self, vpn_id : str):
         LOGGER.debug('VPN_Id: {:s}'.format(str(vpn_id)))
         LOGGER.debug('Request: {:s}'.format(str(request)))
 
         response = jsonify({})
-
         try:
-            target = get_service(self.context_client, vpn_id)
+            context_client = ContextClient()
+
+            target = get_service(context_client, vpn_id)
             if target is not None:
                 if target.service_id.service_uuid.uuid != vpn_id: # pylint: disable=no-member
                     raise Exception('Service retrieval failed. Wrong Service Id was returned')
@@ -53,7 +46,7 @@ class L2VPN_Service(Resource):
                 response.status_code = HTTP_OK if service_status == service_ready_status else HTTP_GATEWAYTIMEOUT
                 return response
 
-            target = get_slice(self.context_client, vpn_id)
+            target = get_slice(context_client, vpn_id)
             if target is not None:
                 if target.slice_id.slice_uuid.uuid != vpn_id: # pylint: disable=no-member
                     raise Exception('Slice retrieval failed. Wrong Slice Id was returned')
@@ -80,7 +73,8 @@ class L2VPN_Service(Resource):
         service_id_request.service_uuid.uuid = vpn_id
 
         try:
-            self.service_client.DeleteService(service_id_request)
+            service_client = ServiceClient()
+            service_client.DeleteService(service_id_request)
             response = jsonify({})
             response.status_code = HTTP_NOCONTENT
         except Exception as e: # pylint: disable=broad-except
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py
index 6d39cfe2d..e0de1b732 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_Services.py
@@ -19,7 +19,6 @@ from flask.json import jsonify
 from flask_restful import Resource
 from werkzeug.exceptions import UnsupportedMediaType
 from common.Constants import DEFAULT_CONTEXT_UUID
-from common.Settings import get_setting
 from service.client.ServiceClient import ServiceClient
 from service.proto.context_pb2 import Service, ServiceStatusEnum, ServiceTypeEnum
 from slice.client.SliceClient import SliceClient
@@ -32,13 +31,6 @@ from .tools.Validator import validate_message
 LOGGER = logging.getLogger(__name__)
 
 class L2VPN_Services(Resource):
-    def __init__(self) -> None:
-        super().__init__()
-        self.service_client = ServiceClient(
-            get_setting('SERVICESERVICE_SERVICE_HOST'), get_setting('SERVICESERVICE_SERVICE_PORT_GRPC'))
-        self.slice_client = SliceClient(
-            get_setting('SLICESERVICE_SERVICE_HOST'), get_setting('SLICESERVICE_SERVICE_PORT_GRPC'))
-
     @HTTP_AUTH.login_required
     def get(self):
         return {}
@@ -62,7 +54,8 @@ class L2VPN_Services(Resource):
                     service_request.service_type = ServiceTypeEnum.SERVICETYPE_L3NM
                     service_request.service_status.service_status = ServiceStatusEnum.SERVICESTATUS_PLANNED
 
-                    service_reply = self.service_client.CreateService(service_request)
+                    service_client = ServiceClient()
+                    service_reply = service_client.CreateService(service_request)
                     if service_reply != service_request.service_id: # pylint: disable=no-member
                         raise Exception('Service creation failed. Wrong Service Id was returned')
                 elif vpn_service_type == 'vpls':
@@ -72,7 +65,8 @@ class L2VPN_Services(Resource):
                     slice_request.slice_id.slice_uuid.uuid = vpn_service['vpn-id']
                     slice_request.slice_status.slice_status = SliceStatusEnum.SLICESTATUS_PLANNED
 
-                    slice_reply = self.slice_client.CreateSlice(slice_request)
+                    slice_client = SliceClient()
+                    slice_reply = slice_client.CreateSlice(slice_request)
                     if slice_reply != slice_request.slice_id: # pylint: disable=no-member
                         raise Exception('Slice creation failed. Wrong Slice Id was returned')
 
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py
index 2c0245b9a..3e7928067 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/L2VPN_SiteNetworkAccesses.py
@@ -204,25 +204,20 @@ def process_list_site_network_access(
     return response
 
 class L2VPN_SiteNetworkAccesses(Resource):
-    def __init__(self) -> None:
-        super().__init__()
-        self.context_client = ContextClient(
-            get_setting('CONTEXTSERVICE_SERVICE_HOST'), get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC'))
-        self.service_client = ServiceClient(
-            get_setting('SERVICESERVICE_SERVICE_HOST'), get_setting('SERVICESERVICE_SERVICE_PORT_GRPC'))
-        self.slice_client = SliceClient(
-            get_setting('SLICESERVICE_SERVICE_HOST'), get_setting('SLICESERVICE_SERVICE_PORT_GRPC'))
-
     @HTTP_AUTH.login_required
     def post(self, site_id : str):
         if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
         LOGGER.debug('Site_Id: {:s}'.format(str(site_id)))
-        return process_list_site_network_access(
-            self.context_client, self.service_client, self.slice_client, request.json)
+        context_client = ContextClient()
+        service_client = ServiceClient()
+        slice_client = SliceClient()
+        return process_list_site_network_access(context_client, service_client, slice_client, request.json)
 
     @HTTP_AUTH.login_required
     def put(self, site_id : str):
         if not request.is_json: raise UnsupportedMediaType('JSON payload is required')
         LOGGER.debug('Site_Id: {:s}'.format(str(site_id)))
-        return process_list_site_network_access(
-            self.context_client, self.service_client, self.slice_client, request.json)
+        context_client = ContextClient()
+        service_client = ServiceClient()
+        slice_client = SliceClient()
+        return process_list_site_network_access(context_client, service_client, slice_client, request.json)
diff --git a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/__init__.py b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/__init__.py
index 79be6b743..c8b23bcee 100644
--- a/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/__init__.py
+++ b/src/compute/service/rest_server/nbi_plugins/ietf_l2vpn/__init__.py
@@ -21,7 +21,7 @@ from .L2VPN_Services import L2VPN_Services
 from .L2VPN_Service import L2VPN_Service
 from .L2VPN_SiteNetworkAccesses import L2VPN_SiteNetworkAccesses
 
-URL_PREFIX      = '/ietf-l2vpn-svc:l2vpn-svc'
+URL_PREFIX = '/ietf-l2vpn-svc:l2vpn-svc'
 
 def _add_resource(rest_server : RestServer, resource : Resource, *urls, **kwargs):
     urls = [(URL_PREFIX + url) for url in urls]
diff --git a/src/compute/tests/MockService_Dependencies.py b/src/compute/tests/MockService_Dependencies.py
new file mode 100644
index 000000000..8b0e4b3cc
--- /dev/null
+++ b/src/compute/tests/MockService_Dependencies.py
@@ -0,0 +1,58 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+from typing import Union
+from common.Constants import ServiceNameEnum
+from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name
+from common.tests.MockServicerImpl_Context import MockServicerImpl_Context
+from common.tests.MockServicerImpl_Service import MockServicerImpl_Service
+from common.tests.MockServicerImpl_Slice import MockServicerImpl_Slice
+from common.tools.service.GenericGrpcService import GenericGrpcService
+from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server
+from service.proto.service_pb2_grpc import add_ServiceServiceServicer_to_server
+from slice.proto.slice_pb2_grpc import add_SliceServiceServicer_to_server
+
+LOCAL_HOST = '127.0.0.1'
+
+SERVICE_CONTEXT = ServiceNameEnum.CONTEXT
+SERVICE_SERVICE = ServiceNameEnum.SERVICE
+SERVICE_SLICE = ServiceNameEnum.SLICE
+
+class MockService_Dependencies(GenericGrpcService):
+    # Mock Service implementing Context, Service and Slice to simplify unitary tests of Compute
+
+    def __init__(self, bind_port: Union[str, int]) -> None:
+        super().__init__(bind_port, LOCAL_HOST, enable_health_servicer=False, cls_name='MockService')
+
+    # pylint: disable=attribute-defined-outside-init
+    def install_servicers(self):
+        self.context_servicer = MockServicerImpl_Context()
+        add_ContextServiceServicer_to_server(self.context_servicer, self.server)
+
+        self.service_servicer = MockServicerImpl_Service()
+        add_ServiceServiceServicer_to_server(self.service_servicer, self.server)
+
+        self.slice_servicer = MockServicerImpl_Slice()
+        add_SliceServiceServicer_to_server(self.slice_servicer, self.server)
+
+    def configure_env_vars(self):
+        os.environ[get_env_var_name(SERVICE_CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     )] = str(self.bind_address)
+        os.environ[get_env_var_name(SERVICE_CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(self.bind_port)
+
+        os.environ[get_env_var_name(SERVICE_SERVICE, ENVVAR_SUFIX_SERVICE_HOST     )] = str(self.bind_address)
+        os.environ[get_env_var_name(SERVICE_SERVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(self.bind_port)
+
+        os.environ[get_env_var_name(SERVICE_SLICE, ENVVAR_SUFIX_SERVICE_HOST     )] = str(self.bind_address)
+        os.environ[get_env_var_name(SERVICE_SLICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(self.bind_port)
diff --git a/src/compute/tests/PrepareTestScenario.py b/src/compute/tests/PrepareTestScenario.py
new file mode 100644
index 000000000..d534a4a28
--- /dev/null
+++ b/src/compute/tests/PrepareTestScenario.py
@@ -0,0 +1,52 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os, pytest, time
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_HTTP, get_env_var_name, get_service_port_http)
+from compute.service.rest_server.RestServer import RestServer
+from compute.service.rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn
+from compute.tests.MockService_Dependencies import MockService_Dependencies
+from .mock_osm.MockOSM import MockOSM
+from .Constants import WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD
+
+LOCAL_HOST = '127.0.0.1'
+MOCKSERVICE_PORT = 10000
+COMPUTE_SERVICE_PORT = MOCKSERVICE_PORT + get_service_port_http(ServiceNameEnum.COMPUTE)    # avoid privileged ports
+os.environ[get_env_var_name(ServiceNameEnum.COMPUTE, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
+os.environ[get_env_var_name(ServiceNameEnum.COMPUTE, ENVVAR_SUFIX_SERVICE_PORT_HTTP)] = str(COMPUTE_SERVICE_PORT)
+
+@pytest.fixture(scope='session')
+def mock_service():
+    _service = MockService_Dependencies(MOCKSERVICE_PORT)
+    _service.configure_env_vars()
+    _service.start()
+    yield _service
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def compute_service_rest(mock_service):  # pylint: disable=redefined-outer-name
+    _rest_server = RestServer()
+    register_ietf_l2vpn(_rest_server)
+    _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 osm_wim(compute_service_rest): # pylint: disable=redefined-outer-name
+    wim_url = 'http://{:s}:{:d}'.format(LOCAL_HOST, COMPUTE_SERVICE_PORT)
+    return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)
diff --git a/src/compute/tests/test_unitary.py b/src/compute/tests/test_unitary.py
index 1fbc74ecc..05c45c1b3 100644
--- a/src/compute/tests/test_unitary.py
+++ b/src/compute/tests/test_unitary.py
@@ -12,75 +12,16 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging, os, pytest, time
-from common.tests.MockService import MockService
-from common.tests.MockServicerImpl_Context import MockServicerImpl_Context
-from common.tests.MockServicerImpl_Service import MockServicerImpl_Service
-from common.tests.MockServicerImpl_Slice import MockServicerImpl_Slice
-from compute.Config import RESTAPI_SERVICE_PORT, RESTAPI_BASE_URL
-from compute.service.rest_server.RestServer import RestServer
-from context.proto.context_pb2_grpc import add_ContextServiceServicer_to_server
-from service.proto.service_pb2_grpc import add_ServiceServiceServicer_to_server
-from slice.proto.slice_pb2_grpc import add_SliceServiceServicer_to_server
+import logging
 from .mock_osm.MockOSM import MockOSM
-from .Constants import (
-    SERVICE_CONNECTION_POINTS_1, SERVICE_CONNECTION_POINTS_2, SERVICE_TYPE, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)
+from .Constants import SERVICE_CONNECTION_POINTS_1, SERVICE_CONNECTION_POINTS_2, SERVICE_TYPE
+from .PrepareTestScenario import ( # pylint: disable=unused-import
+    # be careful, order of symbols is important here!
+    mock_service, compute_service_rest, osm_wim)
 
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
 
-LOCALHOST = '127.0.0.1'
-MOCKSERVER_GRPC_PORT = 10000
-COMPUTE_RESTAPI_PORT = 10000 + RESTAPI_SERVICE_PORT # avoid privileged ports
-
-class MockService_ContextService(MockService):
-    # Mock Server implementing Context and Service to simplify unitary tests of Compute
-
-    def __init__(self, cls_name='MockService_Service'):
-        super().__init__(LOCALHOST, MOCKSERVER_GRPC_PORT, cls_name=cls_name)
-
-    # pylint: disable=attribute-defined-outside-init
-    def install_servicers(self):
-        self.context_servicer = MockServicerImpl_Context()
-        add_ContextServiceServicer_to_server(self.context_servicer, self.server)
-        self.service_servicer = MockServicerImpl_Service()
-        add_ServiceServiceServicer_to_server(self.service_servicer, self.server)
-        self.slice_servicer = MockServicerImpl_Slice()
-        add_SliceServiceServicer_to_server(self.slice_servicer, self.server)
-
-os.environ['CONTEXTSERVICE_SERVICE_HOST'] = LOCALHOST
-os.environ['CONTEXTSERVICE_SERVICE_PORT_GRPC'] = str(MOCKSERVER_GRPC_PORT)
-os.environ['SERVICESERVICE_SERVICE_HOST'] = LOCALHOST
-os.environ['SERVICESERVICE_SERVICE_PORT_GRPC'] = str(MOCKSERVER_GRPC_PORT)
-os.environ['SLICESERVICE_SERVICE_HOST'] = LOCALHOST
-os.environ['SLICESERVICE_SERVICE_PORT_GRPC'] = str(MOCKSERVER_GRPC_PORT)
-
-# NBI Plugin IETF L2VPN requires environment variables CONTEXTSERVICE_SERVICE_HOST, CONTEXTSERVICE_SERVICE_PORT_GRPC,
-# SERVICESERVICE_SERVICE_HOST, and SERVICESERVICE_SERVICE_PORT_GRPC to work properly.
-# pylint: disable=wrong-import-position,ungrouped-imports
-from compute.service.rest_server.nbi_plugins.ietf_l2vpn import register_ietf_l2vpn
-
-@pytest.fixture(scope='session')
-def mockservice():
-    _service = MockService_ContextService()
-    _service.start()
-    yield _service
-    _service.stop()
-
-@pytest.fixture(scope='session')
-def compute_service_rest(mockservice):  # pylint: disable=redefined-outer-name
-    _rest_server = RestServer(port=COMPUTE_RESTAPI_PORT, base_url=RESTAPI_BASE_URL)
-    register_ietf_l2vpn(_rest_server)
-    _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 osm_wim(compute_service_rest): # pylint: disable=redefined-outer-name
-    wim_url = 'http://{:s}:{:d}'.format(LOCALHOST, COMPUTE_RESTAPI_PORT)
-    return MockOSM(wim_url, WIM_MAPPING, WIM_USERNAME, WIM_PASSWORD)
 
 def test_compute_create_connectivity_service_rest_api(osm_wim : MockOSM): # pylint: disable=redefined-outer-name
     osm_wim.create_connectivity_service(SERVICE_TYPE, SERVICE_CONNECTION_POINTS_1)
-- 
GitLab


From e45720d1772872fd3b38b338a90828e19d0a59a2 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 17:25:00 +0200
Subject: [PATCH 30/60] InterDomain component: - Migrated to use new generic
 gRPC servicer and clients - Migrated to use new settings framework -
 Commented wrong/outdated unitary tests (to be coded) - Minor code
 formatting/styling

---
 src/interdomain/client/InterdomainClient.py   |   8 +-
 src/interdomain/service/InterdomainService.py |  65 +----
 .../service/InterdomainServiceServicerImpl.py |  27 +-
 .../service/RemoteDomainClients.py            |   6 +-
 src/interdomain/service/__main__.py           |  51 +---
 src/interdomain/tests/test_unitary.py         | 259 +++++++++---------
 6 files changed, 175 insertions(+), 241 deletions(-)

diff --git a/src/interdomain/client/InterdomainClient.py b/src/interdomain/client/InterdomainClient.py
index 345dfa3ec..a34f31537 100644
--- a/src/interdomain/client/InterdomainClient.py
+++ b/src/interdomain/client/InterdomainClient.py
@@ -13,6 +13,8 @@
 # limitations under the License.
 
 import grpc, logging
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_grpc
 from common.tools.client.RetryDecorator import retry, delay_exponential
 from common.tools.grpc.Tools import grpc_message_to_json_string
 from interdomain.proto.context_pb2 import AuthenticationResult, Slice, SliceId, SliceStatus, TeraFlowController
@@ -24,8 +26,10 @@ DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
 RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
 
 class InterdomainClient:
-    def __init__(self, address, port):
-        self.endpoint = '{:s}:{:s}'.format(str(address), str(port))
+    def __init__(self, host=None, port=None):
+        if not host: host = get_service_host(ServiceNameEnum.INTERDOMAIN)
+        if not port: port = get_service_port_grpc(ServiceNameEnum.INTERDOMAIN)
+        self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
         LOGGER.debug('Creating channel to {:s}...'.format(self.endpoint))
         self.channel = None
         self.stub = None
diff --git a/src/interdomain/service/InterdomainService.py b/src/interdomain/service/InterdomainService.py
index debc943cf..cca6bcb85 100644
--- a/src/interdomain/service/InterdomainService.py
+++ b/src/interdomain/service/InterdomainService.py
@@ -12,65 +12,18 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import grpc, logging
-from concurrent import futures
-from grpc_health.v1.health import HealthServicer, OVERALL_HEALTH
-from grpc_health.v1.health_pb2 import HealthCheckResponse
-from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
-from context.client.ContextClient import ContextClient
-from interdomain.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_port_grpc
+from common.tools.service.GenericGrpcService import GenericGrpcService
 from interdomain.proto.interdomain_pb2_grpc import add_InterdomainServiceServicer_to_server
-from slice.client.SliceClient import SliceClient
 from .InterdomainServiceServicerImpl import InterdomainServiceServicerImpl
 from .RemoteDomainClients import RemoteDomainClients
 
-BIND_ADDRESS = '0.0.0.0'
-LOGGER = logging.getLogger(__name__)
+class InterdomainService(GenericGrpcService):
+    def __init__(self, remote_domain_clients : RemoteDomainClients, cls_name: str = __name__) -> None:
+        port = get_service_port_grpc(ServiceNameEnum.INTERDOMAIN)
+        super().__init__(port, cls_name=cls_name)
+        self.interdomain_servicer = InterdomainServiceServicerImpl(remote_domain_clients)
 
-class InterdomainService:
-    def __init__(
-        self, context_client : ContextClient, slice_client : SliceClient, remote_domain_clients : RemoteDomainClients,
-        address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD
-    ):
-        self.context_client = context_client
-        self.slice_client = slice_client
-        self.remote_domain_clients = remote_domain_clients
-        self.address = address
-        self.port = port
-        self.endpoint = None
-        self.max_workers = max_workers
-        self.grace_period = grace_period
-        self.interdomain_servicer = None
-        self.health_servicer = None
-        self.pool = None
-        self.server = None
-
-    def start(self):
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
-        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
-            str(self.endpoint), str(self.max_workers)))
-
-        self.pool = futures.ThreadPoolExecutor(max_workers=self.max_workers)
-        self.server = grpc.server(self.pool) # , interceptors=(tracer_interceptor,))
-
-        self.interdomain_servicer = InterdomainServiceServicerImpl(
-            self.context_client, self.slice_client, self.remote_domain_clients)
+    def install_servicers(self):
         add_InterdomainServiceServicer_to_server(self.interdomain_servicer, self.server)
-
-        self.health_servicer = HealthServicer(
-            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
-        add_HealthServicer_to_server(self.health_servicer, self.server)
-
-        port = self.server.add_insecure_port(self.endpoint)
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(port))
-        LOGGER.info('Listening on {:s}...'.format(str(self.endpoint)))
-        self.server.start()
-        self.health_servicer.set(OVERALL_HEALTH, HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
-
-        LOGGER.debug('Service started')
-
-    def stop(self):
-        LOGGER.debug('Stopping service (grace period {:s} seconds)...'.format(str(self.grace_period)))
-        self.health_servicer.enter_graceful_shutdown()
-        self.server.stop(self.grace_period)
-        LOGGER.debug('Service stopped')
diff --git a/src/interdomain/service/InterdomainServiceServicerImpl.py b/src/interdomain/service/InterdomainServiceServicerImpl.py
index e76297625..20ae74eef 100644
--- a/src/interdomain/service/InterdomainServiceServicerImpl.py
+++ b/src/interdomain/service/InterdomainServiceServicerImpl.py
@@ -14,7 +14,7 @@
 
 import grpc, logging
 from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
-from common.tools.grpc.Tools import grpc_message_to_json_string
+#from common.tools.grpc.Tools import grpc_message_to_json_string
 from context.client.ContextClient import ContextClient
 from context.proto.context_pb2 import SliceStatusEnum
 from interdomain.proto.context_pb2 import AuthenticationResult, Slice, SliceId, SliceStatus, TeraFlowController
@@ -29,18 +29,16 @@ METHOD_NAMES = ['RequestSlice', 'Authenticate', 'LookUpSlice', 'OrderSliceFromCa
 METRICS = create_metrics(SERVICE_NAME, METHOD_NAMES)
 
 class InterdomainServiceServicerImpl(InterdomainServiceServicer):
-    def __init__(
-        self, context_client : ContextClient, slice_client : SliceClient,
-        remote_domain_clients : RemoteDomainClients
-    ):
+    def __init__(self, remote_domain_clients : RemoteDomainClients):
         LOGGER.debug('Creating Servicer...')
-        self.context_client = context_client
-        self.slice_client = slice_client
         self.remote_domain_clients = remote_domain_clients
         LOGGER.debug('Servicer Created')
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def RequestSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
+        context_client = ContextClient()
+        slice_client = SliceClient()
+
         domains_to_endpoints = {}
         local_domain_uuid = None
         for slice_endpoint_id in request.slice_endpoint_ids:
@@ -90,7 +88,7 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer):
                 if remote_slice.slice_status.slice_status != SliceStatusEnum.SLICESTATUS_ACTIVE:
                     raise Exception('Remote Slice creation failed. Wrong Slice status returned')
 
-            #self.context_client.SetSlice(remote_slice)
+            #context_client.SetSlice(remote_slice)
             #subslice_id = reply.slice_subslice_ids.add()
             #subslice_id.CopyFrom(remote_slice.slice_id)
 
@@ -112,7 +110,7 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer):
             slice_endpoint_id.device_id.device_uuid.uuid = 'R1@D2'
             slice_endpoint_id.endpoint_uuid.uuid = '2/1'
 
-        local_slice_reply = self.slice_client.CreateSlice(local_slice_request)
+        local_slice_reply = slice_client.CreateSlice(local_slice_request)
         if local_slice_reply != local_slice_request.slice_id: # pylint: disable=no-member
             raise Exception('Local Slice creation failed. Wrong Slice Id was returned')
 
@@ -120,7 +118,7 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer):
         subslice_id.context_id.context_uuid.uuid = local_slice_request.slice_id.context_id.context_uuid.uuid
         subslice_id.slice_uuid.uuid = local_slice_request.slice_id.slice_uuid.uuid
 
-        self.context_client.SetSlice(reply)
+        context_client.SetSlice(reply)
         return reply.slice_id
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
@@ -133,7 +131,8 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer):
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def LookUpSlice(self, request : Slice, context : grpc.ServicerContext) -> SliceId:
         try:
-            slice_ = self.context_client.GetSlice(request.slice_id)
+            context_client = ContextClient()
+            slice_ = context_client.GetSlice(request.slice_id)
             return slice_.slice_id
         except grpc.RpcError:
             #LOGGER.exception('Unable to get slice({:s})'.format(grpc_message_to_json_string(request.slice_id)))
@@ -146,7 +145,9 @@ class InterdomainServiceServicerImpl(InterdomainServiceServicer):
 
     @safe_and_metered_rpc_method(METRICS, LOGGER)
     def CreateSliceAndAddToCatalog(self, request : Slice, context : grpc.ServicerContext) -> Slice:
-        reply = self.slice_client.CreateSlice(request)
+        context_client = ContextClient()
+        slice_client = SliceClient()
+        reply = slice_client.CreateSlice(request)
         if reply != request.slice_id: # pylint: disable=no-member
             raise Exception('Slice creation failed. Wrong Slice Id was returned')
-        return self.context_client.GetSlice(request.slice_id)
+        return context_client.GetSlice(request.slice_id)
diff --git a/src/interdomain/service/RemoteDomainClients.py b/src/interdomain/service/RemoteDomainClients.py
index 709aa3c07..8fde3f442 100644
--- a/src/interdomain/service/RemoteDomainClients.py
+++ b/src/interdomain/service/RemoteDomainClients.py
@@ -26,16 +26,16 @@ class RemoteDomainClients:
         self.peer_domain = {}
 
     def add_peer(
-            self, domain_name : str, address : str, port : int, context_uuid : str = DEFAULT_CONTEXT_UUID
+            self, domain_name : str, host : str, port : int, context_uuid : str = DEFAULT_CONTEXT_UUID
         ) -> None:
         while True:
             try:
-                remote_teraflow_ip = socket.gethostbyname(address)
+                remote_teraflow_ip = socket.gethostbyname(host)
                 if len(remote_teraflow_ip) > 0: break
             except socket.gaierror as e:
                 if str(e) == '[Errno -2] Name or service not known': continue
 
-        interdomain_client = InterdomainClient(address, port)
+        interdomain_client = InterdomainClient(host=host, port=port)
         request = TeraFlowController()
         request.context_id.context_uuid.uuid = DEFAULT_CONTEXT_UUID # pylint: disable=no-member
         request.ip_address = get_setting('INTERDOMAINSERVICE_SERVICE_HOST', default='0.0.0.0')
diff --git a/src/interdomain/service/__main__.py b/src/interdomain/service/__main__.py
index ff19271ee..c0a078f4d 100644
--- a/src/interdomain/service/__main__.py
+++ b/src/interdomain/service/__main__.py
@@ -14,14 +14,12 @@
 
 import logging, signal, sys, threading
 from prometheus_client import start_http_server
-from common.Settings import get_setting, wait_for_environment_variables
-from context.client.ContextClient import ContextClient
-from interdomain.service.RemoteDomainClients import RemoteDomainClients
-from interdomain.Config import (
-    CONTEXT_SERVICE_HOST, CONTEXT_SERVICE_PORT, SLICE_SERVICE_HOST, SLICE_SERVICE_PORT, GRPC_SERVICE_PORT,
-    GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT)
-from slice.client.SliceClient import SliceClient
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
+    get_service_port_grpc, wait_for_environment_variables)
 from .InterdomainService import InterdomainService
+from .RemoteDomainClients import RemoteDomainClients
 
 terminate = threading.Event()
 LOGGER : logging.Logger = None
@@ -33,55 +31,36 @@ def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
 def main():
     global LOGGER # pylint: disable=global-statement
 
-    grpc_service_port       = get_setting('INTERDOMAINSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT      )
-    max_workers             = get_setting('MAX_WORKERS',                          default=GRPC_MAX_WORKERS       )
-    grace_period            = get_setting('GRACE_PERIOD',                         default=GRPC_GRACE_PERIOD      )
-    log_level               = get_setting('LOG_LEVEL',                            default=LOG_LEVEL              )
-    metrics_port            = get_setting('METRICS_PORT',                         default=METRICS_PORT           )
-
+    log_level = get_log_level()
     logging.basicConfig(level=log_level)
     LOGGER = logging.getLogger(__name__)
 
     wait_for_environment_variables([
-        'CONTEXTSERVICE_SERVICE_HOST', 'CONTEXTSERVICE_SERVICE_PORT_GRPC',
-        'SLICESERVICE_SERVICE_HOST', 'SLICESERVICE_SERVICE_PORT_GRPC',
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
+        get_env_var_name(ServiceNameEnum.SLICE,   ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.SLICE,   ENVVAR_SUFIX_SERVICE_PORT_GRPC),
     ])
 
-    context_service_host    = get_setting('CONTEXTSERVICE_SERVICE_HOST',          default=CONTEXT_SERVICE_HOST   )
-    context_service_port    = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC',     default=CONTEXT_SERVICE_PORT   )
-    slice_service_host      = get_setting('SLICESERVICE_SERVICE_HOST',            default=SLICE_SERVICE_HOST     )
-    slice_service_port      = get_setting('SLICESERVICE_SERVICE_PORT_GRPC',       default=SLICE_SERVICE_PORT     )
-
     signal.signal(signal.SIGINT,  signal_handler)
     signal.signal(signal.SIGTERM, signal_handler)
 
     LOGGER.info('Starting...')
 
     # Start metrics server
+    metrics_port = get_metrics_port()
     start_http_server(metrics_port)
 
-    # Initialize Context Client
-    if context_service_host is None or context_service_port is None:
-        raise Exception('Wrong address({:s}):port({:s}) of Context component'.format(
-            str(context_service_host), str(context_service_port)))
-    context_client = ContextClient(context_service_host, context_service_port)
-
-    # Initialize Slice Client
-    if slice_service_host is None or slice_service_port is None:
-        raise Exception('Wrong address({:s}):port({:s}) of Slice component'.format(
-            str(slice_service_host), str(slice_service_port)))
-    slice_client = SliceClient(slice_service_host, slice_service_port)
-
     # Define remote domain clients
     remote_domain_clients = RemoteDomainClients()
 
     # Starting Interdomain service
-    grpc_service = InterdomainService(
-        context_client, slice_client, remote_domain_clients, port=grpc_service_port, max_workers=max_workers,
-        grace_period=grace_period)
+    grpc_service = InterdomainService(remote_domain_clients)
     grpc_service.start()
 
-    remote_domain_clients.add_peer('remote-teraflow', 'remote-teraflow', GRPC_SERVICE_PORT)
+    # TODO: improve with configuration the definition of the remote peers
+    interdomain_service_port_grpc = get_service_port_grpc(ServiceNameEnum.INTERDOMAIN)
+    remote_domain_clients.add_peer('remote-teraflow', 'remote-teraflow', interdomain_service_port_grpc)
 
     # Wait for Ctrl+C or termination signal
     while not terminate.wait(timeout=0.1): pass
diff --git a/src/interdomain/tests/test_unitary.py b/src/interdomain/tests/test_unitary.py
index bcc6bb9c9..7fe1acc7c 100644
--- a/src/interdomain/tests/test_unitary.py
+++ b/src/interdomain/tests/test_unitary.py
@@ -13,134 +13,131 @@
 # limitations under the License.
 
 
-import logging, grpc
-import os
-import sqlite3
-
-import pytest
-from typing import Tuple
-
-from interdomain.proto import context_pb2, kpi_sample_types_pb2, monitoring_pb2
-from interdomain.client.interdomain_client import InterdomainClient
-from interdomain.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
-from interdomain.service.InterdomainService import InterdomainService
-
-from common.orm.Database import Database
-from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
-from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
-from common.message_broker.MessageBroker import MessageBroker
-
-LOGGER = logging.getLogger(__name__)
-LOGGER.setLevel(logging.DEBUG)
-
-###########################
-# Tests Setup
-###########################
-
-SERVER_ADDRESS = '127.0.0.1'
-LISTEN_ADDRESS = '[::]'
-GRPC_PORT_MONITORING = 9090
-
-GRPC_PORT_CONTEXT    = 10000 + grpc_port_context    # avoid privileged ports
-
-SCENARIOS = [ # comment/uncomment scenarios to activate/deactivate them in the test unit
-    ('all_inmemory', DatabaseBackendEnum.INMEMORY, {},           MessageBrokerBackendEnum.INMEMORY, {}          ),
-]
-
-
-# This fixture will be requested by test cases and last during testing session
-@pytest.fixture(scope='session')
-def interdomain_service():
-    LOGGER.warning('interdomain_service begin')
-
-    interdomain_port    = GRPC_INTERDOMAIN_PORT
-    max_workers     = GRPC_MAX_WORKERS
-    grace_period    = GRPC_GRACE_PERIOD
-
-    LOGGER.info('Initializing InterdomainService...')
-    grpc_service = InterdomainService(port=interdomain_port, max_workers=max_workers, grace_period=grace_period)
-    server = grpc_service.start()
-
-    # yield the server, when test finishes, execution will resume to stop it
-    LOGGER.warning('interdomain_service yielding')
-    yield server
-
-    LOGGER.info('Terminating InterdomainService...')
-    grpc_service.stop()
-
-# This fixture will be requested by test cases and last during testing session.
-# The client requires the server, so client fixture has the server as dependency.
-@pytest.fixture(scope='session')
-def interdomain_client(interdomain_service):
-    LOGGER.warning('interdomain_client begin')
-    client = InterdomainClient(server=SERVER_ADDRESS, port=GRPC_PORT_INTERDOMAIN)  # instantiate the client
-    LOGGER.warning('interdomain_client returning')
-    return client
-
-# This fixture will be requested by test cases and last during testing session.
-@pytest.fixture(scope='session')
-def create_TeraFlowController():
-    LOGGER.warning('create_TeraFlowController begin')
-    # form request
-    tf_ctl                  = context_pb2.TeraFlowController()
-    tf_ctl.context_id       = context_pb2.ContextId()
-    tf_ctl.context_id.context_uuid = context_pb2.Uuid()
-    tf_ctl.context_id.context_uuid.uuid = str(1) 
-    tf_ctl.ip_address       = "127.0.0.1"
-    tf_ctl.port      	    = 9090
-    return tf_ctl
-
-@pytest.fixture(scope='session')
-def create_TransportSlice():
-    LOGGER.warning('create_TransportSlice begin')
-
-    # form request
-    slice_req              = slice_pb2.TransportSlice()
-    slice_req.contextId    = context_pb2.ContextId()
-    slice_req.contextId.context_uuid = context_pb2.Uuid()
-    slice_req.contextId.context_uuid.uuid = str(1) 
-    slice_req.slice_id     = context_pb2.Uuid()
-    slice_req.slice_id.context_uuid.uuid = str(1) 
-
-    return slice_req
-
-
-###########################
-# Tests Implementation
-###########################
-
-
-# Test case that makes use of client fixture to test server's CreateKpi method
-def test_Authenticate(interdomain_client,create_TeraFlowController):
-    # make call to server
-    LOGGER.warning('test_Authenticate requesting')
-    response = interdomain_client.Authenticate(create_TeraFlowController)
-    LOGGER.debug(str(response))
-    assert isinstance(response, context.AuthenticationResult)
-
-# Test case that makes use of client fixture to test server's MonitorKpi method
-def test_LookUpSlice(interdomain_client,create_TransportSlice):
-    LOGGER.warning('test_LookUpSlice begin')
-
-    response = interdomain_client.LookUpSlice(create_TransportSlice)
-    LOGGER.debug(str(response))
-    assert isinstance(response, slice.SliceId)
-
-# Test case that makes use of client fixture to test server's GetStreamKpi method
-def test_CreateSliceAndAddToCatalog(interdomain_client,create_TransportSlice):
-    LOGGER.warning('test_CreateSliceAndAddToCatalog begin')
-    response = interdomain_client.CreateSliceAndAddToCatalog(create_TransportSlice)
-    LOGGER.debug(str(response))
-    assert isinstance(response, slice.SliceId)
-
-# Test case that makes use of client fixture to test server's IncludeKpi method
-def test_OrderSliceFromCatalog(interdomain_client,create_TransportSlice):
-    # make call to server
-    LOGGER.warning('test_OrderSliceFromCatalog requesting')
-    response = interdomain_client.OrderSliceFromCatalog(create_TransportSlice)
-    LOGGER.debug(str(response))
-    assert isinstance(response, slice.SliceId)
-
-
-
-
+#import logging, grpc
+#import os
+#import sqlite3
+#
+#import pytest
+#from typing import Tuple
+#
+#from interdomain.proto import context_pb2, kpi_sample_types_pb2, monitoring_pb2
+#from interdomain.client.interdomain_client import InterdomainClient
+#from interdomain.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
+#from interdomain.service.InterdomainService import InterdomainService
+#
+#from common.orm.Database import Database
+#from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
+#from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
+#from common.message_broker.MessageBroker import MessageBroker
+#
+#LOGGER = logging.getLogger(__name__)
+#LOGGER.setLevel(logging.DEBUG)
+#
+############################
+## Tests Setup
+############################
+#
+#SERVER_ADDRESS = '127.0.0.1'
+#LISTEN_ADDRESS = '[::]'
+#GRPC_PORT_MONITORING = 9090
+#
+#GRPC_PORT_CONTEXT    = 10000 + grpc_port_context    # avoid privileged ports
+#
+#SCENARIOS = [ # comment/uncomment scenarios to activate/deactivate them in the test unit
+#    ('all_inmemory', DatabaseBackendEnum.INMEMORY, {},           MessageBrokerBackendEnum.INMEMORY, {}          ),
+#]
+#
+#
+## This fixture will be requested by test cases and last during testing session
+#@pytest.fixture(scope='session')
+#def interdomain_service():
+#    LOGGER.warning('interdomain_service begin')
+#
+#    interdomain_port    = GRPC_INTERDOMAIN_PORT
+#    max_workers     = GRPC_MAX_WORKERS
+#    grace_period    = GRPC_GRACE_PERIOD
+#
+#    LOGGER.info('Initializing InterdomainService...')
+#    grpc_service = InterdomainService(port=interdomain_port, max_workers=max_workers, grace_period=grace_period)
+#    server = grpc_service.start()
+#
+#    # yield the server, when test finishes, execution will resume to stop it
+#    LOGGER.warning('interdomain_service yielding')
+#    yield server
+#
+#    LOGGER.info('Terminating InterdomainService...')
+#    grpc_service.stop()
+#
+## This fixture will be requested by test cases and last during testing session.
+## The client requires the server, so client fixture has the server as dependency.
+#@pytest.fixture(scope='session')
+#def interdomain_client(interdomain_service):
+#    LOGGER.warning('interdomain_client begin')
+#    client = InterdomainClient(server=SERVER_ADDRESS, port=GRPC_PORT_INTERDOMAIN)  # instantiate the client
+#    LOGGER.warning('interdomain_client returning')
+#    return client
+#
+## This fixture will be requested by test cases and last during testing session.
+#@pytest.fixture(scope='session')
+#def create_TeraFlowController():
+#    LOGGER.warning('create_TeraFlowController begin')
+#    # form request
+#    tf_ctl                  = context_pb2.TeraFlowController()
+#    tf_ctl.context_id       = context_pb2.ContextId()
+#    tf_ctl.context_id.context_uuid = context_pb2.Uuid()
+#    tf_ctl.context_id.context_uuid.uuid = str(1) 
+#    tf_ctl.ip_address       = "127.0.0.1"
+#    tf_ctl.port      	    = 9090
+#    return tf_ctl
+#
+#@pytest.fixture(scope='session')
+#def create_TransportSlice():
+#    LOGGER.warning('create_TransportSlice begin')
+#
+#    # form request
+#    slice_req              = slice_pb2.TransportSlice()
+#    slice_req.contextId    = context_pb2.ContextId()
+#    slice_req.contextId.context_uuid = context_pb2.Uuid()
+#    slice_req.contextId.context_uuid.uuid = str(1) 
+#    slice_req.slice_id     = context_pb2.Uuid()
+#    slice_req.slice_id.context_uuid.uuid = str(1) 
+#
+#    return slice_req
+#
+#
+############################
+## Tests Implementation
+############################
+#
+#
+## Test case that makes use of client fixture to test server's CreateKpi method
+#def test_Authenticate(interdomain_client,create_TeraFlowController):
+#    # make call to server
+#    LOGGER.warning('test_Authenticate requesting')
+#    response = interdomain_client.Authenticate(create_TeraFlowController)
+#    LOGGER.debug(str(response))
+#    assert isinstance(response, context.AuthenticationResult)
+#
+## Test case that makes use of client fixture to test server's MonitorKpi method
+#def test_LookUpSlice(interdomain_client,create_TransportSlice):
+#    LOGGER.warning('test_LookUpSlice begin')
+#
+#    response = interdomain_client.LookUpSlice(create_TransportSlice)
+#    LOGGER.debug(str(response))
+#    assert isinstance(response, slice.SliceId)
+#
+## Test case that makes use of client fixture to test server's GetStreamKpi method
+#def test_CreateSliceAndAddToCatalog(interdomain_client,create_TransportSlice):
+#    LOGGER.warning('test_CreateSliceAndAddToCatalog begin')
+#    response = interdomain_client.CreateSliceAndAddToCatalog(create_TransportSlice)
+#    LOGGER.debug(str(response))
+#    assert isinstance(response, slice.SliceId)
+#
+## Test case that makes use of client fixture to test server's IncludeKpi method
+#def test_OrderSliceFromCatalog(interdomain_client,create_TransportSlice):
+#    # make call to server
+#    LOGGER.warning('test_OrderSliceFromCatalog requesting')
+#    response = interdomain_client.OrderSliceFromCatalog(create_TransportSlice)
+#    LOGGER.debug(str(response))
+#    assert isinstance(response, slice.SliceId)
+#
-- 
GitLab


From ee6f34dec6958cf55a18d424f169960e175a35e9 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Thu, 19 May 2022 17:26:06 +0200
Subject: [PATCH 31/60] Minor change in OpticalCentralizedAttackDetector

---
 .../OpticalCentralizedAttackDetectorServiceServicerImpl.py      | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py
index 9c77a959c..f27441e48 100644
--- a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py
+++ b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py
@@ -17,7 +17,7 @@ from influxdb import InfluxDBClient
 from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
 from context.client.ContextClient import ContextClient
 from context.Config import GRPC_SERVICE_PORT as CONTEXT_GRPC_SERVICE_PORT
-from monitoring.client.monitoring_client import MonitoringClient
+from monitoring.client.MonitoringClient import MonitoringClient
 from monitoring.Config import GRPC_SERVICE_PORT as MONITORING_GRPC_SERVICE_PORT
 from service.client.ServiceClient import ServiceClient
 from service.Config import GRPC_SERVICE_PORT as SERVICE_GRPC_SERVICE_PORT
-- 
GitLab


From 6a1bf009a70d520825f9d24dc0706f1ddca0859b Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Fri, 20 May 2022 13:08:16 +0200
Subject: [PATCH 32/60] Common tools: - added helper methods to object_factory

---
 src/common/tools/object_factory/EndPoint.py | 20 +++++++++++++++++++-
 src/common/tools/object_factory/Link.py     |  5 +++++
 2 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/src/common/tools/object_factory/EndPoint.py b/src/common/tools/object_factory/EndPoint.py
index d75060436..9eca5e963 100644
--- a/src/common/tools/object_factory/EndPoint.py
+++ b/src/common/tools/object_factory/EndPoint.py
@@ -13,13 +13,21 @@
 # limitations under the License.
 
 import copy
-from typing import Dict, List, Optional
+from typing import Dict, List, Optional, Tuple
 
 def json_endpoint_id(device_id : Dict, endpoint_uuid : str, topology_id : Optional[Dict] = None):
     result = {'device_id': copy.deepcopy(device_id), 'endpoint_uuid': {'uuid': endpoint_uuid}}
     if topology_id is not None: result['topology_id'] = copy.deepcopy(topology_id)
     return result
 
+def json_endpoint_ids(
+        device_id : Dict, endpoint_descriptors : List[Tuple[str, str, List[int]]], topology_id : Optional[Dict] = None
+    ):
+    return [
+        json_endpoint_id(device_id, endpoint_uuid, topology_id=topology_id)
+        for endpoint_uuid, _, _ in endpoint_descriptors
+    ]
+
 def json_endpoint(
         device_id : Dict, endpoint_uuid : str, endpoint_type : str, topology_id : Optional[Dict] = None,
         kpi_sample_types : List[int] = []
@@ -31,3 +39,13 @@ def json_endpoint(
     }
     if len(kpi_sample_types) > 0: result['kpi_sample_types'] = copy.deepcopy(kpi_sample_types)
     return result
+
+def json_endpoints(
+        device_id : Dict, endpoint_descriptors : List[Tuple[str, str, List[int]]], topology_id : Optional[Dict] = None
+    ):
+    return [
+        json_endpoint(
+            device_id, endpoint_uuid, endpoint_type, topology_id=topology_id,
+            kpi_sample_types=endpoint_sample_types)
+        for endpoint_uuid, endpoint_type, endpoint_sample_types in endpoint_descriptors
+    ]
diff --git a/src/common/tools/object_factory/Link.py b/src/common/tools/object_factory/Link.py
index fac279459..624cbb8dc 100644
--- a/src/common/tools/object_factory/Link.py
+++ b/src/common/tools/object_factory/Link.py
@@ -15,6 +15,11 @@
 import copy
 from typing import Dict, List
 
+def get_link_uuid(a_device_id : Dict, a_endpoint_id : Dict, z_device_id : Dict, z_endpoint_id : Dict) -> str:
+    return '{:s}/{:s}=={:s}/{:s}'.format(
+        a_device_id['device_uuid']['uuid'], a_endpoint_id['endpoint_uuid']['uuid'],
+        z_device_id['device_uuid']['uuid'], z_endpoint_id['endpoint_uuid']['uuid'])
+
 def json_link_id(link_uuid : str):
     return {'link_uuid': {'uuid': link_uuid}}
 
-- 
GitLab


From 1ed5b8301c6e55ec2a65256b0e47832ed6aacf20 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Fri, 20 May 2022 13:09:23 +0200
Subject: [PATCH 33/60] Monitoring component: - Migrated to use new generic
 gRPC servicer and clients - Migrated to use new settings framework - Improved
 definition of unitary tests and solved some bugs - Minor code
 formatting/styling

---
 src/monitoring/client/MonitoringClient.py     |  99 +++++
 src/monitoring/client/monitoring_client.py    |  75 ----
 src/monitoring/service/EventTools.py          |  17 +-
 src/monitoring/service/MonitoringService.py   |  70 +--
 .../service/MonitoringServiceServicerImpl.py  |  55 +--
 src/monitoring/service/__main__.py            |  59 +--
 src/monitoring/tests/Messages.py              |  49 +++
 src/monitoring/tests/Objects.py               |  30 ++
 src/monitoring/tests/test_unitary.py          | 415 +++++++++---------
 9 files changed, 439 insertions(+), 430 deletions(-)
 create mode 100644 src/monitoring/client/MonitoringClient.py
 delete mode 100644 src/monitoring/client/monitoring_client.py
 create mode 100644 src/monitoring/tests/Messages.py
 create mode 100644 src/monitoring/tests/Objects.py

diff --git a/src/monitoring/client/MonitoringClient.py b/src/monitoring/client/MonitoringClient.py
new file mode 100644
index 000000000..d8b39b8bf
--- /dev/null
+++ b/src/monitoring/client/MonitoringClient.py
@@ -0,0 +1,99 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import grpc, logging
+from typing import Iterator
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_host, get_service_port_grpc
+from common.tools.client.RetryDecorator import retry, delay_exponential
+from common.tools.grpc.Tools import grpc_message_to_json_string
+from monitoring.proto.context_pb2 import Empty
+from monitoring.proto.monitoring_pb2 import Kpi, KpiDescriptor, KpiId, MonitorKpiRequest
+from monitoring.proto.monitoring_pb2_grpc import MonitoringServiceStub
+
+LOGGER = logging.getLogger(__name__)
+MAX_RETRIES = 15
+DELAY_FUNCTION = delay_exponential(initial=0.01, increment=2.0, maximum=5.0)
+RETRY_DECORATOR = retry(max_retries=MAX_RETRIES, delay_function=DELAY_FUNCTION, prepare_method_name='connect')
+
+class MonitoringClient:
+    def __init__(self, host=None, port=None):
+        if not host: host = get_service_host(ServiceNameEnum.MONITORING)
+        if not port: port = get_service_port_grpc(ServiceNameEnum.MONITORING)
+        self.endpoint = '{:s}:{:s}'.format(str(host), str(port))
+        LOGGER.debug('Creating channel to {:s}...'.format(str(self.endpoint)))
+        self.channel = None
+        self.stub = None
+        self.connect()
+        LOGGER.debug('Channel created')
+
+    def connect(self):
+        self.channel = grpc.insecure_channel(self.endpoint)
+        self.stub = MonitoringServiceStub(self.channel)
+
+    def close(self):
+        if self.channel is not None: self.channel.close()
+        self.channel = None
+        self.stub = None
+
+    @RETRY_DECORATOR
+    def CreateKpi(self, request : KpiDescriptor) -> KpiId:
+        LOGGER.debug('CreateKpi: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.CreateKpi(request)
+        LOGGER.debug('CreateKpi result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def GetKpiDescriptor(self, request : KpiId) -> KpiDescriptor:
+        LOGGER.debug('GetKpiDescriptor: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetKpiDescriptor(request)
+        LOGGER.debug('GetKpiDescriptor result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def IncludeKpi(self, request : Kpi) -> Empty:
+        LOGGER.debug('IncludeKpi: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.IncludeKpi(request)
+        LOGGER.debug('IncludeKpi result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def MonitorKpi(self, request : MonitorKpiRequest) -> Empty:
+        LOGGER.debug('MonitorKpi: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.MonitorKpi(request)
+        LOGGER.debug('MonitorKpi result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def GetStreamKpi(self, request : KpiId) -> Iterator[Kpi]:
+        LOGGER.debug('GetStreamKpi: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetStreamKpi(request)
+        LOGGER.debug('GetStreamKpi result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+    @RETRY_DECORATOR
+    def GetInstantKpi(self, request : KpiId) -> Kpi:
+        LOGGER.debug('GetInstantKpi: {:s}'.format(grpc_message_to_json_string(request)))
+        response = self.stub.GetInstantKpi(request)
+        LOGGER.debug('GetInstantKpi result: {:s}'.format(grpc_message_to_json_string(response)))
+        return response
+
+
+if __name__ == '__main__':
+    import sys
+    # get port
+    _port = sys.argv[1] if len(sys.argv) > 1 else '7070'
+
+    # make call to server
+    client = MonitoringClient(port=_port)
diff --git a/src/monitoring/client/monitoring_client.py b/src/monitoring/client/monitoring_client.py
deleted file mode 100644
index 62bfb519e..000000000
--- a/src/monitoring/client/monitoring_client.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import sys
-import grpc
-
-from monitoring.proto import monitoring_pb2
-from monitoring.proto import monitoring_pb2_grpc
-from monitoring.proto import context_pb2
-
-from common.logger import getJSONLogger
-LOGGER = getJSONLogger('monitoring-client')
-LOGGER.setLevel('DEBUG')
-
-class MonitoringClient:
-
-    def __init__(self, server='monitoring', port='7070'):
-        endpoint = '{}:{}'.format(server, port)
-        LOGGER.info('init monitoringClient {}'.format(endpoint))
-        self.channel = grpc.insecure_channel(endpoint)
-        self.server = monitoring_pb2_grpc.MonitoringServiceStub(self.channel)
-
-    def CreateKpi(self, request):
-        LOGGER.info('CreateKpi: {}'.format(request))
-        response = self.server.CreateKpi(request)
-        LOGGER.info('CreateKpi result: {}'.format(response))
-        return response
-
-    def MonitorKpi(self, request):
-        LOGGER.info('MonitorKpi: {}'.format(request))
-        response = self.server.MonitorKpi(request)
-        LOGGER.info('MonitorKpi result: {}'.format(response))
-        return response
-
-    def IncludeKpi(self, request):
-        LOGGER.info('IncludeKpi: {}'.format(request))
-        response = self.server.IncludeKpi(request)
-        LOGGER.info('IncludeKpi result: {}'.format(response))
-        return response
-
-    def GetStreamKpi(self, request):
-        LOGGER.info('GetStreamKpi: {}'.format(request))
-        response = self.server.GetStreamKpi(request)
-        LOGGER.info('GetStreamKpi result: {}'.format(response))
-        yield monitoring_pb2.Kpi()
-
-    def GetInstantKpi(self, request):
-        LOGGER.info('GetInstantKpi: {}'.format(request))
-        response = self.server.GetInstantKpi(request)
-        LOGGER.info('GetInstantKpi result: {}'.format(response))
-        return monitoring_pb2.Kpi()
-
-    def GetKpiDescriptor(self, request):
-        LOGGER.info('GetKpiDescriptor: {}'.format(request))
-        response = self.server.GetKpiDescriptor(request)
-        LOGGER.info('GetKpiDescriptor result: {}'.format(response))
-        return response
-
-if __name__ == '__main__':
-    # get port
-    port = sys.argv[1] if len(sys.argv) > 1 else '7070'
-
-    # make call to server
-    client = MonitoringClient(port=port)
diff --git a/src/monitoring/service/EventTools.py b/src/monitoring/service/EventTools.py
index 636556425..04c06e742 100644
--- a/src/monitoring/service/EventTools.py
+++ b/src/monitoring/service/EventTools.py
@@ -19,26 +19,27 @@ import grpc
 
 from common.rpc_method_wrapper.ServiceExceptions import ServiceException
 from context.client.ContextClient import ContextClient
-from context.proto import kpi_sample_types_pb2
+#from context.proto import kpi_sample_types_pb2
 from context.proto.context_pb2 import Empty, EventTypeEnum
 
 from common.logger import getJSONLogger
-from monitoring.client.monitoring_client import MonitoringClient
+from monitoring.client.MonitoringClient import MonitoringClient
 from monitoring.proto import monitoring_pb2
 
 LOGGER = getJSONLogger('monitoringservice-server')
 LOGGER.setLevel('DEBUG')
 
 class EventsDeviceCollector:
-    def __init__(self, context_client_grpc : ContextClient, monitoring_client_grpc : MonitoringClient) -> None: # pylint: disable=redefined-outer-name
+    def __init__(self) -> None: # pylint: disable=redefined-outer-name
         self._events_queue = Queue()
 
-        self._device_stream     = context_client_grpc.GetDeviceEvents(Empty())
-        self._context_client    = context_client_grpc
-        self._channel           = context_client_grpc.channel
-        self._monitoring_client = monitoring_client_grpc
+        self._context_client_grpc = ContextClient()
+        self._device_stream     = self._context_client_grpc.GetDeviceEvents(Empty())
+        self._context_client    = self._context_client_grpc
+        self._channel           = self._context_client_grpc.channel
+        self._monitoring_client = MonitoringClient(host='127.0.0.1')
 
-        self._device_thread   = threading.Thread(target=self._collect, args=(self._device_stream  ,), daemon=False)
+        self._device_thread   = threading.Thread(target=self._collect, args=(self._device_stream,), daemon=False)
 
     def grpc_server_on(self):
         try:
diff --git a/src/monitoring/service/MonitoringService.py b/src/monitoring/service/MonitoringService.py
index f1ecba366..0736eba43 100644
--- a/src/monitoring/service/MonitoringService.py
+++ b/src/monitoring/service/MonitoringService.py
@@ -12,63 +12,17 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-from concurrent import futures
-
-import grpc, logging
-
-from monitoring.service.MonitoringServiceServicerImpl import MonitoringServiceServicerImpl
-from monitoring.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
-from monitoring.proto.monitoring_pb2_grpc import  add_MonitoringServiceServicer_to_server
-
-from grpc_health.v1 import health
-from grpc_health.v1 import health_pb2
-from grpc_health.v1.health_pb2_grpc import add_HealthServicer_to_server
-
-from common.logger import getJSONLogger
-LOGGER = getJSONLogger('monitoring-server')
-
-BIND_ADDRESS = '0.0.0.0'
-
-class MonitoringService:
-    def __init__(self, address=BIND_ADDRESS, port=GRPC_SERVICE_PORT, max_workers=GRPC_MAX_WORKERS,
-                 grace_period=GRPC_GRACE_PERIOD):
-        self.address = address
-        self.port = port
-        self.endpoint = None
-        self.max_workers = max_workers
-        self.grace_period = grace_period
-        self.monitoring_servicer = None
-        self.health_servicer = None
-        self.pool = None
-        self.server = None
-
-    def start(self):
-        # create gRPC server
-        self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=self.max_workers)) # ,interceptors=(tracer_interceptor,))
-
-        # add monitoring servicer class to gRPC server
+from common.Constants import ServiceNameEnum
+from common.Settings import get_service_port_grpc
+from common.tools.service.GenericGrpcService import GenericGrpcService
+from monitoring.proto.monitoring_pb2_grpc import add_MonitoringServiceServicer_to_server
+from .MonitoringServiceServicerImpl import MonitoringServiceServicerImpl
+
+class MonitoringService(GenericGrpcService):
+    def __init__(self, cls_name: str = __name__) -> None:
+        port = get_service_port_grpc(ServiceNameEnum.MONITORING)
+        super().__init__(port, cls_name=cls_name)
         self.monitoring_servicer = MonitoringServiceServicerImpl()
-        add_MonitoringServiceServicer_to_server(self.monitoring_servicer, self.server)
-
-        # add gRPC health checker servicer class to gRPC server
-        self.health_servicer = health.HealthServicer(
-            experimental_non_blocking=True, experimental_thread_pool=futures.ThreadPoolExecutor(max_workers=1))
-        add_HealthServicer_to_server(self.health_servicer, self.server)
-
-        # start server
-        self.endpoint = '{:s}:{:s}'.format(str(self.address), str(self.port))
-        LOGGER.info('Starting Service (tentative endpoint: {:s}, max_workers: {:s})...'.format(
-            str(self.endpoint), str(self.max_workers)))
-
-        self.server.add_insecure_port(self.endpoint)
-        self.server.start()
-        self.health_servicer.set('', health_pb2.HealthCheckResponse.SERVING) # pylint: disable=maybe-no-member
-
-        LOGGER.debug('Service started')
-
-    def stop(self):
-        LOGGER.debug('Stopping service (grace period {} seconds)...'.format(self.grace_period))
-        self.health_servicer.enter_graceful_shutdown()
-        self.server.stop(self.grace_period)
-        LOGGER.debug('Service stopped')
 
+    def install_servicers(self):
+        add_MonitoringServiceServicer_to_server(self.monitoring_servicer, self.server)
diff --git a/src/monitoring/service/MonitoringServiceServicerImpl.py b/src/monitoring/service/MonitoringServiceServicerImpl.py
index 88cd2d3a8..28c1ed120 100644
--- a/src/monitoring/service/MonitoringServiceServicerImpl.py
+++ b/src/monitoring/service/MonitoringServiceServicerImpl.py
@@ -12,29 +12,21 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import os,grpc, logging
-import socket
-
-from prometheus_client import Summary
-from prometheus_client import Counter
-from common.Settings import get_setting
-
-from monitoring.Config import DEVICE_GRPC_SERVICE_PORT, DEVICE_SERVICE_HOST
+import os, grpc, logging
+from prometheus_client import Counter, Summary
 from monitoring.proto.kpi_sample_types_pb2 import KpiSampleType
 from monitoring.service import SqliteTools, InfluxTools
 from monitoring.proto import monitoring_pb2
 from monitoring.proto import monitoring_pb2_grpc
-
 from common.rpc_method_wrapper.ServiceExceptions import ServiceException
-
 from context.proto import context_pb2
-
 from device.client.DeviceClient import DeviceClient
 from device.proto import device_pb2
 
 LOGGER = logging.getLogger(__name__)
 
-MONITORING_GETINSTANTKPI_REQUEST_TIME = Summary('monitoring_getinstantkpi_processing_seconds', 'Time spent processing monitoring instant kpi request')
+MONITORING_GETINSTANTKPI_REQUEST_TIME = Summary(
+    'monitoring_getinstantkpi_processing_seconds', 'Time spent processing monitoring instant kpi request')
 MONITORING_INCLUDEKPI_COUNTER = Counter('monitoring_includekpi_counter', 'Monitoring include kpi request counter')
 
 INFLUXDB_HOSTNAME = os.environ.get("INFLUXDB_HOSTNAME")
@@ -42,9 +34,6 @@ INFLUXDB_USER = os.environ.get("INFLUXDB_USER")
 INFLUXDB_PASSWORD = os.environ.get("INFLUXDB_PASSWORD")
 INFLUXDB_DATABASE = os.environ.get("INFLUXDB_DATABASE")
 
-DEVICE_SERVICE_HOST = get_setting('DEVICESERVICE_SERVICE_HOST',      default=DEVICE_SERVICE_HOST     )
-DEVICE_SERVICE_PORT = get_setting('DEVICESERVICE_SERVICE_PORT_GRPC', default=DEVICE_GRPC_SERVICE_PORT)
-
 
 class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceServicer):
     def __init__(self):
@@ -52,13 +41,14 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
 
         # Init sqlite monitoring db
         self.sql_db = SqliteTools.SQLite('monitoring.db')
-        self.deviceClient = DeviceClient(address=DEVICE_SERVICE_HOST, port=DEVICE_GRPC_SERVICE_PORT)  # instantiate the client
 
         # Create influx_db client
         self.influx_db = InfluxTools.Influx(INFLUXDB_HOSTNAME,"8086",INFLUXDB_USER,INFLUXDB_PASSWORD,INFLUXDB_DATABASE)
 
     # CreateKpi (CreateKpiRequest) returns (KpiId) {}
-    def CreateKpi(self, request : monitoring_pb2.KpiDescriptor, grpc_context : grpc.ServicerContext) -> monitoring_pb2.KpiId :
+    def CreateKpi(
+        self, request : monitoring_pb2.KpiDescriptor, grpc_context : grpc.ServicerContext
+    ) -> monitoring_pb2.KpiId:
         # CREATEKPI_COUNTER_STARTED.inc()
         LOGGER.info('CreateKpi')
         try:
@@ -71,7 +61,8 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
             kpi_endpoint_id = request.endpoint_id.endpoint_uuid.uuid
             kpi_service_id  = request.service_id.service_uuid.uuid
 
-            data = self.sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
+            data = self.sql_db.insert_KPI(
+                kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
 
             kpi_id.kpi_id.uuid = str(data)
 
@@ -87,7 +78,9 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
             grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
 
     # rpc MonitorKpi (MonitorKpiRequest) returns (context.Empty) {}
-    def MonitorKpi ( self, request : monitoring_pb2.MonitorKpiRequest, grpc_context : grpc.ServicerContext) -> context_pb2.Empty:
+    def MonitorKpi(
+        self, request : monitoring_pb2.MonitorKpiRequest, grpc_context : grpc.ServicerContext
+    ) -> context_pb2.Empty:
 
         LOGGER.info('MonitorKpi')
         try:
@@ -97,25 +90,23 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
             kpiDescriptor = self.GetKpiDescriptor(request.kpi_id, grpc_context)
 
             monitor_device_request.kpi_descriptor.CopyFrom(kpiDescriptor)
-            monitor_device_request.kpi_id.kpi_id.uuid                               = request.kpi_id.kpi_id.uuid
-            monitor_device_request.sampling_duration_s                              = request.sampling_duration_s
-            monitor_device_request.sampling_interval_s                              = request.sampling_interval_s
+            monitor_device_request.kpi_id.kpi_id.uuid  = request.kpi_id.kpi_id.uuid
+            monitor_device_request.sampling_duration_s = request.sampling_duration_s
+            monitor_device_request.sampling_interval_s = request.sampling_interval_s
 
-            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-            if s.connect_ex((DEVICE_SERVICE_HOST, DEVICE_GRPC_SERVICE_PORT)) == 0:
-                self.deviceClient.MonitorDeviceKpi(monitor_device_request)
-            else:
-                LOGGER.warning('Device service is not reachable')
+            device_client = DeviceClient()
+            device_client.MonitorDeviceKpi(monitor_device_request)
 
-            return context_pb2.Empty()
         except ServiceException as e:
             LOGGER.exception('MonitorKpi exception')
             # CREATEKPI_COUNTER_FAILED.inc()
             grpc_context.abort(e.code, e.details)
         except Exception as e:  # pragma: no cover
             LOGGER.exception('MonitorKpi exception')
+            grpc_context.abort(grpc.StatusCode.INTERNAL, str(e))
             # CREATEKPI_COUNTER_FAILED.inc()
 
+        return context_pb2.Empty()
 
     # rpc IncludeKpi(IncludeKpiRequest)  returns(context.Empty)    {}
     def IncludeKpi(self, request : monitoring_pb2.Kpi, grpc_context : grpc.ServicerContext) -> context_pb2.Empty:
@@ -145,7 +136,7 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
             LOGGER.exception('IncludeKpi exception')
             # CREATEKPI_COUNTER_FAILED.inc()
             grpc_context.abort(e.code, e.details)
-        except Exception as e:  # pragma: no cover
+        except Exception:  # pragma: no cover
             LOGGER.exception('IncludeKpi exception')
             # CREATEKPI_COUNTER_FAILED.inc()
         return context_pb2.Empty()
@@ -162,7 +153,9 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
         return monitoring_pb2.Kpi()
 
 
-    def GetKpiDescriptor(self, request : monitoring_pb2.KpiId, grpc_context : grpc.ServicerContext) -> monitoring_pb2.KpiDescriptor:
+    def GetKpiDescriptor(
+        self, request : monitoring_pb2.KpiId, grpc_context : grpc.ServicerContext
+    ) -> monitoring_pb2.KpiDescriptor:
         LOGGER.info('getting Kpi by KpiID')
         try:
             kpi_db = self.sql_db.get_KPI(int(request.kpi_id.uuid))
@@ -183,5 +176,5 @@ class MonitoringServiceServicerImpl(monitoring_pb2_grpc.MonitoringServiceService
             LOGGER.exception('GetKpiDescriptor exception')
             grpc_context.abort(e.code, e.details)
 
-        except Exception as e:  # pragma: no cover
+        except Exception:  # pragma: no cover
             LOGGER.exception('GetKpiDescriptor exception')
diff --git a/src/monitoring/service/__main__.py b/src/monitoring/service/__main__.py
index 7835b4fc8..714046517 100644
--- a/src/monitoring/service/__main__.py
+++ b/src/monitoring/service/__main__.py
@@ -12,44 +12,27 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging, signal, sys, threading, socket
-
-from common.Settings import get_setting, wait_for_environment_variables
-from context.client.ContextClient import ContextClient
-from monitoring.Config import (
-    GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, LOG_LEVEL, METRICS_PORT, CONTEXT_GRPC_SERVICE_PORT,
-    CONTEXT_SERVICE_HOST)
-
-from monitoring.client.monitoring_client import MonitoringClient
-from monitoring.proto import monitoring_pb2
-from monitoring.service.EventTools import EventsDeviceCollector
-from monitoring.service.MonitoringService import MonitoringService
-
+import logging, signal, sys, threading
 from prometheus_client import start_http_server
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_log_level, get_metrics_port,
+    wait_for_environment_variables)
+from monitoring.proto import monitoring_pb2
+from .EventTools import EventsDeviceCollector
+from .MonitoringService import MonitoringService
 
 terminate = threading.Event()
 LOGGER = None
-LOCALHOST = '127.0.0.1'
 
-def signal_handler(signal, frame):
+def signal_handler(signal, frame): # pylint: disable=redefined-outer-name
     LOGGER.warning('Terminate signal received')
     terminate.set()
 
 def start_monitoring():
     LOGGER.info('Start Monitoring...',)
 
-    grpc_service_port    = get_setting('MONITORINGSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT        )
-    context_service_host = get_setting('CONTEXTSERVICE_SERVICE_HOST',         default=CONTEXT_SERVICE_HOST     )
-    context_service_port = get_setting('CONTEXTSERVICE_SERVICE_PORT_GRPC',    default=CONTEXT_GRPC_SERVICE_PORT)
-
-    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    if s.connect_ex((context_service_host, int(context_service_port))) != 0:
-        LOGGER.info('Context service is not reachable')
-        return
-
-    context_client_grpc = ContextClient(address=context_service_host, port=context_service_port)
-    monitoring_client = MonitoringClient(server=LOCALHOST, port=grpc_service_port)  # instantiate the client
-    events_collector = EventsDeviceCollector(context_client_grpc, monitoring_client)
+    events_collector = EventsDeviceCollector()
     events_collector.start()
 
     # Iterate while terminate is not set
@@ -64,8 +47,7 @@ def start_monitoring():
                 monitor_kpi_request.kpi_id.CopyFrom(kpi_id)
                 monitor_kpi_request.sampling_duration_s = 86400
                 monitor_kpi_request.sampling_interval_s = 30
-
-                monitoring_client.MonitorKpi(monitor_kpi_request)
+                events_collector._monitoring_client.MonitorKpi(monitor_kpi_request)
     else:
         # Terminate is set, looping terminates
         LOGGER.warning("Stopping execution...")
@@ -73,31 +55,28 @@ def start_monitoring():
     events_collector.start()
 
 def main():
-    global LOGGER
-
-    grpc_service_port = get_setting('MONITORINGSERVICE_SERVICE_PORT_GRPC', default=GRPC_SERVICE_PORT)
-    max_workers       = get_setting('MAX_WORKERS',                         default=GRPC_MAX_WORKERS )
-    grace_period      = get_setting('GRACE_PERIOD',                        default=GRPC_GRACE_PERIOD)
-    log_level         = get_setting('LOG_LEVEL',                           default=LOG_LEVEL        )
-    metrics_port      = get_setting('METRICS_PORT',                        default=METRICS_PORT     )
+    global LOGGER # pylint: disable=global-statement
 
+    log_level = get_log_level()
     logging.basicConfig(level=log_level)
     LOGGER = logging.getLogger(__name__)
 
     wait_for_environment_variables([
-        'CONTEXTSERVICE_SERVICE_HOST', 'CONTEXTSERVICE_SERVICE_PORT_GRPC',
-        'DEVICESERVICE_SERVICE_HOST', 'DEVICESERVICE_SERVICE_PORT_GRPC'
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_HOST     ),
+        get_env_var_name(ServiceNameEnum.CONTEXT, ENVVAR_SUFIX_SERVICE_PORT_GRPC),
     ])
 
     signal.signal(signal.SIGINT,  signal_handler)
     signal.signal(signal.SIGTERM, signal_handler)
 
     LOGGER.info('Starting...')
+
     # Start metrics server
+    metrics_port = get_metrics_port()
     start_http_server(metrics_port)
 
     # Starting monitoring service
-    grpc_service = MonitoringService(port=grpc_service_port, max_workers=max_workers, grace_period=grace_period)
+    grpc_service = MonitoringService()
     grpc_service.start()
 
     start_monitoring()
@@ -112,4 +91,4 @@ def main():
     return 0
 
 if __name__ == '__main__':
-    sys.exit(main())
\ No newline at end of file
+    sys.exit(main())
diff --git a/src/monitoring/tests/Messages.py b/src/monitoring/tests/Messages.py
new file mode 100644
index 000000000..dd4db01fd
--- /dev/null
+++ b/src/monitoring/tests/Messages.py
@@ -0,0 +1,49 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from monitoring.proto import monitoring_pb2
+from monitoring.proto.kpi_sample_types_pb2 import KpiSampleType
+
+def kpi():
+    _kpi                    = monitoring_pb2.Kpi()
+    _kpi.kpi_id.kpi_id.uuid = 'KPIID0000'   # pylint: disable=maybe-no-member
+    return _kpi
+
+def kpi_id():
+    _kpi_id             = monitoring_pb2.KpiId()
+    _kpi_id.kpi_id.uuid = str(1)            # pylint: disable=maybe-no-member
+    return _kpi_id
+
+def create_kpi_request():
+    _create_kpi_request                                = monitoring_pb2.KpiDescriptor()
+    _create_kpi_request.kpi_description                = 'KPI Description Test'
+    _create_kpi_request.kpi_sample_type                = KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED
+    _create_kpi_request.device_id.device_uuid.uuid     = 'DEV1'     # pylint: disable=maybe-no-member
+    _create_kpi_request.service_id.service_uuid.uuid   = 'SERV1'    # pylint: disable=maybe-no-member
+    _create_kpi_request.endpoint_id.endpoint_uuid.uuid = 'END1'     # pylint: disable=maybe-no-member
+    return _create_kpi_request
+
+def monitor_kpi_request(kpi_uuid, sampling_duration_s, sampling_interval_s):
+    _monitor_kpi_request                     = monitoring_pb2.MonitorKpiRequest()
+    _monitor_kpi_request.kpi_id.kpi_id.uuid  = kpi_uuid   # pylint: disable=maybe-no-member
+    _monitor_kpi_request.sampling_duration_s = sampling_duration_s
+    _monitor_kpi_request.sampling_interval_s = sampling_interval_s
+    return _monitor_kpi_request
+
+def include_kpi_request():
+    _include_kpi_request                    = monitoring_pb2.Kpi()
+    _include_kpi_request.kpi_id.kpi_id.uuid = str(1)    # pylint: disable=maybe-no-member
+    _include_kpi_request.timestamp          = "2021-10-12T13:14:42Z"
+    _include_kpi_request.kpi_value.intVal   = 500       # pylint: disable=maybe-no-member
+    return _include_kpi_request
diff --git a/src/monitoring/tests/Objects.py b/src/monitoring/tests/Objects.py
new file mode 100644
index 000000000..852da6bc9
--- /dev/null
+++ b/src/monitoring/tests/Objects.py
@@ -0,0 +1,30 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from common.tools.object_factory.Device import (
+    json_device_emulated_connect_rules, json_device_emulated_packet_router_disabled)
+from context.proto.kpi_sample_types_pb2 import KpiSampleType
+
+PACKET_PORT_SAMPLE_TYPES = [
+    KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED,
+    KpiSampleType.KPISAMPLETYPE_PACKETS_RECEIVED,
+    KpiSampleType.KPISAMPLETYPE_BYTES_TRANSMITTED,
+    KpiSampleType.KPISAMPLETYPE_BYTES_RECEIVED,
+]
+
+DEVICE_DEV1_UUID          = 'DEV1'
+ENDPOINT_END1_UUID        = 'END1'
+DEVICE_DEV1_ENDPOINT_DEFS = [(ENDPOINT_END1_UUID, 'copper', PACKET_PORT_SAMPLE_TYPES)]
+DEVICE_DEV1               = json_device_emulated_packet_router_disabled(DEVICE_DEV1_UUID)
+DEVICE_DEV1_CONNECT_RULES = json_device_emulated_connect_rules(DEVICE_DEV1_ENDPOINT_DEFS)
diff --git a/src/monitoring/tests/test_unitary.py b/src/monitoring/tests/test_unitary.py
index 0701c5ce8..d3799689e 100644
--- a/src/monitoring/tests/test_unitary.py
+++ b/src/monitoring/tests/test_unitary.py
@@ -12,36 +12,35 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import logging
-import os
-import socket
-import pytest
+import copy, logging, os, pytest
 from typing import Tuple
-
-
-from monitoring.client.monitoring_client import MonitoringClient
-from monitoring.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD, DEVICE_GRPC_SERVICE_PORT
-from monitoring.proto import context_pb2, monitoring_pb2
-from monitoring.proto.kpi_sample_types_pb2 import KpiSampleType
-from monitoring.service import SqliteTools, InfluxTools
-from monitoring.service.MonitoringService import MonitoringService
-from monitoring.service.EventTools import EventsDeviceCollector
-
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_service_port_grpc)
 from common.orm.Database import Database
 from common.orm.Factory import get_database_backend, BackendEnum as DatabaseBackendEnum
 from common.message_broker.Factory import get_messagebroker_backend, BackendEnum as MessageBrokerBackendEnum
 from common.message_broker.MessageBroker import MessageBroker
 
-from context.Config import (
-    GRPC_SERVICE_PORT as grpc_port_context,
-    GRPC_MAX_WORKERS as grpc_workers_context,
-    GRPC_GRACE_PERIOD as grpc_grace_context
-)
 from context.client.ContextClient import ContextClient
 from context.service.grpc_server.ContextService import ContextService
-from context.service.Populate import populate
 from context.proto.context_pb2 import EventTypeEnum, DeviceEvent, Device
-from context.tests.Objects import (DEVICE_R1, DEVICE_R1_UUID)
+
+from device.client.DeviceClient import DeviceClient
+from device.service.DeviceService import DeviceService
+from device.service.driver_api.DriverFactory import DriverFactory
+from device.service.driver_api.DriverInstanceCache import DriverInstanceCache
+from device.service.drivers import DRIVERS
+
+from monitoring.client.MonitoringClient import MonitoringClient
+from monitoring.proto import context_pb2, monitoring_pb2
+from monitoring.proto.kpi_sample_types_pb2 import KpiSampleType
+from monitoring.service import SqliteTools, InfluxTools
+from monitoring.service.MonitoringService import MonitoringService
+from monitoring.service.EventTools import EventsDeviceCollector
+from monitoring.tests.Messages import create_kpi_request, include_kpi_request, kpi, kpi_id, monitor_kpi_request
+from monitoring.tests.Objects import DEVICE_DEV1, DEVICE_DEV1_CONNECT_RULES, DEVICE_DEV1_UUID
+
 
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
@@ -50,18 +49,19 @@ LOGGER.setLevel(logging.DEBUG)
 # Tests Setup
 ###########################
 
-SERVER_ADDRESS = '127.0.0.1'
-LISTEN_ADDRESS = '[::]'
-GRPC_PORT_MONITORING = 7070
+LOCAL_HOST = '127.0.0.1'
 
-GRPC_PORT_CONTEXT    = 10000 + grpc_port_context    # avoid privileged ports
-DEVICE_GRPC_SERVICE_PORT = 10000 + DEVICE_GRPC_SERVICE_PORT # avoid privileged ports
-MONITORING_GRPC_SERVICE_PORT = GRPC_PORT_MONITORING # avoid privileged ports
+CONTEXT_SERVICE_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.CONTEXT) # 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(CONTEXT_SERVICE_PORT)
 
+DEVICE_SERVICE_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.DEVICE) # avoid privileged ports
+os.environ[get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
+os.environ[get_env_var_name(ServiceNameEnum.DEVICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(DEVICE_SERVICE_PORT)
 
-SCENARIOS = [ # comment/uncomment scenarios to activate/deactivate them in the test unit
-    ('all_inmemory', DatabaseBackendEnum.INMEMORY, {},           MessageBrokerBackendEnum.INMEMORY, {}          ),
-]
+MONITORING_SERVICE_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.MONITORING) # avoid privileged ports
+os.environ[get_env_var_name(ServiceNameEnum.MONITORING, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
+os.environ[get_env_var_name(ServiceNameEnum.MONITORING, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(MONITORING_SERVICE_PORT)
 
 INFLUXDB_HOSTNAME = os.environ.get("INFLUXDB_HOSTNAME")
 INFLUXDB_PORT = os.environ.get("INFLUXDB_PORT")
@@ -69,49 +69,61 @@ INFLUXDB_USER = os.environ.get("INFLUXDB_USER")
 INFLUXDB_PASSWORD = os.environ.get("INFLUXDB_PASSWORD")
 INFLUXDB_DATABASE = os.environ.get("INFLUXDB_DATABASE")
 
-@pytest.fixture(scope='session', ids=[str(scenario[0]) for scenario in SCENARIOS], params=SCENARIOS)
-def context_db_mb(request) -> Tuple[Database, MessageBroker]:
-    name,db_backend,db_settings,mb_backend,mb_settings = request.param
-    msg = 'Running scenario {:s} db_backend={:s}, db_settings={:s}, mb_backend={:s}, mb_settings={:s}...'
-    LOGGER.info(msg.format(str(name), str(db_backend.value), str(db_settings), str(mb_backend.value), str(mb_settings)))
-    _database = Database(get_database_backend(backend=db_backend, **db_settings))
-    _message_broker = MessageBroker(get_messagebroker_backend(backend=mb_backend, **mb_settings))
+@pytest.fixture(scope='session')
+def context_db_mb() -> Tuple[Database, MessageBroker]:
+    _database = Database(get_database_backend(backend=DatabaseBackendEnum.INMEMORY))
+    _message_broker = MessageBroker(get_messagebroker_backend(backend=MessageBrokerBackendEnum.INMEMORY))
     yield _database, _message_broker
     _message_broker.terminate()
 
 @pytest.fixture(scope='session')
-def context_service_grpc(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
-    database = context_db_mb[0]
+def context_service(context_db_mb : Tuple[Database, MessageBroker]): # pylint: disable=redefined-outer-name
+    database, message_broker = context_db_mb
     database.clear_all()
-    _service = ContextService(
-        database, context_db_mb[1], port=GRPC_PORT_CONTEXT, max_workers=grpc_workers_context,
-        grace_period=grpc_grace_context)
+    _service = ContextService(database, message_broker)
     _service.start()
     yield _service
     _service.stop()
 
 @pytest.fixture(scope='session')
-def context_client_grpc(context_service_grpc : ContextService): # pylint: disable=redefined-outer-name
-    _client = ContextClient(address='localhost', port=GRPC_PORT_CONTEXT)
+def context_client(context_service : ContextService): # pylint: disable=redefined-outer-name
+    _client = ContextClient()
     yield _client
     _client.close()
 
-
-# This fixture will be requested by test cases and last during testing session
 @pytest.fixture(scope='session')
-def monitoring_service():
-    LOGGER.warning('monitoring_service begin')
+def device_service(context_service : ContextService): # pylint: disable=redefined-outer-name
+    LOGGER.info('Initializing DeviceService...')
+    driver_factory = DriverFactory(DRIVERS)
+    driver_instance_cache = DriverInstanceCache(driver_factory)
+    _service = DeviceService(driver_instance_cache)
+    _service.start()
 
-    service_port    = GRPC_SERVICE_PORT
-    max_workers     = GRPC_MAX_WORKERS
-    grace_period    = GRPC_GRACE_PERIOD
+    # yield the server, when test finishes, execution will resume to stop it
+    LOGGER.info('Yielding DeviceService...')
+    yield _service
+
+    LOGGER.info('Terminating DeviceService...')
+    _service.stop()
+
+@pytest.fixture(scope='session')
+def device_client(device_service : DeviceService): # pylint: disable=redefined-outer-name
+    _client = DeviceClient()
+    yield _client
+    _client.close()
 
+# This fixture will be requested by test cases and last during testing session
+@pytest.fixture(scope='session')
+def monitoring_service(
+        context_service : ContextService,  # pylint: disable=redefined-outer-name
+        device_service : DeviceService     # pylint: disable=redefined-outer-name
+    ):
     LOGGER.info('Initializing MonitoringService...')
-    _service = MonitoringService(port=service_port, max_workers=max_workers, grace_period=grace_period)
+    _service = MonitoringService()
     _service.start()
 
     # yield the server, when test finishes, execution will resume to stop it
-    LOGGER.warning('monitoring_service yielding')
+    LOGGER.info('Yielding MonitoringService...')
     yield _service
 
     LOGGER.info('Terminating MonitoringService...')
@@ -120,224 +132,187 @@ def monitoring_service():
 # This fixture will be requested by test cases and last during testing session.
 # The client requires the server, so client fixture has the server as dependency.
 @pytest.fixture(scope='session')
-def monitoring_client(monitoring_service):
-    LOGGER.warning('monitoring_client begin')
-    client = MonitoringClient(server=SERVER_ADDRESS, port=GRPC_PORT_MONITORING)  # instantiate the client
-    LOGGER.warning('monitoring_client returning')
-    return client
+def monitoring_client(monitoring_service : MonitoringService): # pylint: disable=redefined-outer-name
+    LOGGER.info('Initializing MonitoringClient...')
+    _client = MonitoringClient()
 
-# This fixture will be requested by test cases and last during testing session.
-@pytest.fixture(scope='session')
-def kpi():
-    LOGGER.warning('test_include_kpi begin')
-    # form request
-    kpi                     = monitoring_pb2.Kpi()
-    kpi.kpi_id.kpi_id.uuid  = 'KPIID0000'
-    kpi.kpiDescription      = 'KPI Desc'
-    return kpi
-
-@pytest.fixture(scope='session')
-def kpi_id():
-    LOGGER.warning('test_include_kpi begin')
-
-    # form request
-    kpi_id              = monitoring_pb2.KpiId()
-    kpi_id.kpi_id.uuid  = str(1)
+    # yield the server, when test finishes, execution will resume to stop it
+    LOGGER.info('Yielding MonitoringClient...')
+    yield _client
 
-    return kpi_id
+    LOGGER.info('Closing MonitoringClient...')
+    _client.close()
 
 @pytest.fixture(scope='session')
 def sql_db():
-    sql_db = SqliteTools.SQLite('monitoring.db')
-    return sql_db
+    _sql_db = SqliteTools.SQLite('monitoring.db')
+    return _sql_db
 
 @pytest.fixture(scope='session')
 def influx_db():
-    influx_db = InfluxTools.Influx(INFLUXDB_HOSTNAME, INFLUXDB_PORT, INFLUXDB_USER, INFLUXDB_PASSWORD, INFLUXDB_DATABASE)
-    return influx_db
-
-@pytest.fixture(scope='session')
-def create_kpi_request():
-    LOGGER.warning('test_include_kpi begin')
-
-    create_kpi_request                                  = monitoring_pb2.KpiDescriptor()
-    create_kpi_request.kpi_description                  = 'KPI Description Test'
-    create_kpi_request.kpi_sample_type                  = KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED
-    create_kpi_request.device_id.device_uuid.uuid       = 'DEV1'  # pylint: disable=maybe-no-member
-    create_kpi_request.service_id.service_uuid.uuid     = "SERV1"
-    create_kpi_request.endpoint_id.endpoint_uuid.uuid   = "END1"
-
-    return create_kpi_request
-
-@pytest.fixture(scope='session')
-def monitor_kpi_request():
-    LOGGER.warning('test_monitor_kpi begin')
-
-    monitor_kpi_request                     = monitoring_pb2.MonitorKpiRequest()
-    monitor_kpi_request.kpi_id.kpi_id.uuid  = str(1)
-    monitor_kpi_request.sampling_duration_s = 120
-    monitor_kpi_request.sampling_interval_s = 5
-
-    return monitor_kpi_request
-
-
-@pytest.fixture(scope='session')
-def include_kpi_request():
-    LOGGER.warning('test_include_kpi begin')
-
-    include_kpi_request                     = monitoring_pb2.Kpi()
-    include_kpi_request.kpi_id.kpi_id.uuid  = str(1)
-    include_kpi_request.timestamp           = "2021-10-12T13:14:42Z"
-    include_kpi_request.kpi_value.intVal    = 500
-
-    return include_kpi_request
-
-@pytest.fixture(scope='session')
-def address():
-    address = '127.0.0.1'
-    return address
+    _influx_db = InfluxTools.Influx(
+        INFLUXDB_HOSTNAME, INFLUXDB_PORT, INFLUXDB_USER, INFLUXDB_PASSWORD, INFLUXDB_DATABASE)
+    return _influx_db
 
-@pytest.fixture(scope='session')
-def port():
-    port = 7070
-    return port
 
 ###########################
 # Tests Implementation
 ###########################
 
 # Test case that makes use of client fixture to test server's CreateKpi method
-def test_create_kpi(monitoring_client,create_kpi_request):
+def test_create_kpi(monitoring_client): # pylint: disable=redefined-outer-name
     # make call to server
     LOGGER.warning('test_create_kpi requesting')
-    response = monitoring_client.CreateKpi(create_kpi_request)
+    response = monitoring_client.CreateKpi(create_kpi_request())
     LOGGER.debug(str(response))
     assert isinstance(response, monitoring_pb2.KpiId)
 
 # Test case that makes use of client fixture to test server's MonitorKpi method
-def test_monitor_kpi(monitoring_client,create_kpi_request):
+def test_monitor_kpi(
+        context_client : ContextClient,                 # pylint: disable=redefined-outer-name
+        device_client : DeviceClient,                   # pylint: disable=redefined-outer-name
+        monitoring_client : MonitoringClient,           # pylint: disable=redefined-outer-name
+        context_db_mb : Tuple[Database, MessageBroker]  # pylint: disable=redefined-outer-name
+    ):
     LOGGER.warning('test_monitor_kpi begin')
 
-    response = monitoring_client.CreateKpi(create_kpi_request)
+    context_database = context_db_mb[0]
 
-    monitor_kpi_request                     = monitoring_pb2.MonitorKpiRequest()
-    monitor_kpi_request.kpi_id.kpi_id.uuid  = response.kpi_id.uuid
-    monitor_kpi_request.sampling_duration_s = 120
-    monitor_kpi_request.sampling_interval_s = 5
+    # ----- Clean the database -----------------------------------------------------------------------------------------
+    context_database.clear_all()
 
-    response = monitoring_client.MonitorKpi(monitor_kpi_request)
+    # ----- Dump state of database before create the object ------------------------------------------------------------
+    db_entries = context_database.dump()
+    LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
+    for db_entry in db_entries:
+        LOGGER.info('  [{:>4s}] {:40s} :: {:s}'.format(*db_entry)) # pragma: no cover
+    LOGGER.info('-----------------------------------------------------------')
+    assert len(db_entries) == 0
+
+    # ----- Update the object ------------------------------------------------------------------------------------------
+    LOGGER.info('Adding Device {:s}'.format(DEVICE_DEV1_UUID))
+    device_with_connect_rules = copy.deepcopy(DEVICE_DEV1)
+    device_with_connect_rules['device_config']['config_rules'].extend(DEVICE_DEV1_CONNECT_RULES)
+    response = device_client.AddDevice(Device(**device_with_connect_rules))
+    assert response.device_uuid.uuid == DEVICE_DEV1_UUID
+
+    response = monitoring_client.CreateKpi(create_kpi_request())
+    _monitor_kpi_request = monitor_kpi_request(response.kpi_id.uuid, 120, 5) # pylint: disable=maybe-no-member
+    response = monitoring_client.MonitorKpi(_monitor_kpi_request)
     LOGGER.debug(str(response))
     assert isinstance(response, context_pb2.Empty)
 
 
 # Test case that makes use of client fixture to test server's IncludeKpi method
-def test_include_kpi(monitoring_client,include_kpi_request):
+def test_include_kpi(monitoring_client): # pylint: disable=redefined-outer-name
     # make call to server
     LOGGER.warning('test_include_kpi requesting')
-    response = monitoring_client.IncludeKpi(include_kpi_request)
+    response = monitoring_client.IncludeKpi(include_kpi_request())
     LOGGER.debug(str(response))
     assert isinstance(response, context_pb2.Empty)
 
 # Test case that makes use of client fixture to test server's GetStreamKpi method
-def test_get_stream_kpi(monitoring_client,include_kpi_request):
+def test_get_stream_kpi(monitoring_client): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_getstream_kpi begin')
-    response = monitoring_client.GetStreamKpi(kpi)
+    response = monitoring_client.GetStreamKpi(kpi())
     LOGGER.debug(str(response))
     #assert isinstance(response, monitoring_pb2.Kpi)
 
 # Test case that makes use of client fixture to test server's GetInstantKpi method
-def test_get_instant_kpi(monitoring_client,kpi_id):
+def test_get_instant_kpi(monitoring_client): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_getinstant_kpi begin')
-    response = monitoring_client.GetInstantKpi(kpi_id)
+    response = monitoring_client.GetInstantKpi(kpi_id())
     LOGGER.debug(str(response))
     assert isinstance(response, monitoring_pb2.Kpi)
 
 # Test case that makes use of client fixture to test server's GetInstantKpi method
-def test_get_kpidescritor_kpi(monitoring_client,create_kpi_request):
+def test_get_kpidescritor_kpi(monitoring_client): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_getkpidescritor_kpi begin')
-
-    response = monitoring_client.CreateKpi(create_kpi_request)
-
+    response = monitoring_client.CreateKpi(create_kpi_request())
     response = monitoring_client.GetKpiDescriptor(response)
     LOGGER.debug(str(response))
     assert isinstance(response, monitoring_pb2.KpiDescriptor)
 
-def test_sqlitedb_tools_insert_kpi(sql_db, create_kpi_request):
+def test_sqlitedb_tools_insert_kpi(sql_db): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_sqlitedb_tools_insert_kpi begin')
-
-    kpi_description = create_kpi_request.kpi_description
-    kpi_sample_type = create_kpi_request.kpi_sample_type
-    kpi_device_id = create_kpi_request.device_id.device_uuid.uuid
-    kpi_endpoint_id = create_kpi_request.endpoint_id.endpoint_uuid.uuid
-    kpi_service_id = create_kpi_request.service_id.service_uuid.uuid
+    _create_kpi_request = create_kpi_request()
+    kpi_description = _create_kpi_request.kpi_description                # pylint: disable=maybe-no-member
+    kpi_sample_type = _create_kpi_request.kpi_sample_type                # pylint: disable=maybe-no-member
+    kpi_device_id   = _create_kpi_request.device_id.device_uuid.uuid     # pylint: disable=maybe-no-member
+    kpi_endpoint_id = _create_kpi_request.endpoint_id.endpoint_uuid.uuid # pylint: disable=maybe-no-member
+    kpi_service_id  = _create_kpi_request.service_id.service_uuid.uuid   # pylint: disable=maybe-no-member
 
     response = sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
     assert isinstance(response, int)
 
-def test_sqlitedb_tools_get_kpi(sql_db, create_kpi_request):
+def test_sqlitedb_tools_get_kpi(sql_db): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_sqlitedb_tools_get_kpi begin')
-
-    kpi_description = create_kpi_request.kpi_description
-    kpi_sample_type = create_kpi_request.kpi_sample_type
-    kpi_device_id = create_kpi_request.device_id.device_uuid.uuid
-    kpi_endpoint_id = create_kpi_request.endpoint_id.endpoint_uuid.uuid
-    kpi_service_id = create_kpi_request.service_id.service_uuid.uuid
-
-    kpi_id = sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
-
-    response = sql_db.get_KPI(kpi_id)
+    _create_kpi_request = create_kpi_request()
+    kpi_description = _create_kpi_request.kpi_description                # pylint: disable=maybe-no-member
+    kpi_sample_type = _create_kpi_request.kpi_sample_type                # pylint: disable=maybe-no-member
+    kpi_device_id   = _create_kpi_request.device_id.device_uuid.uuid     # pylint: disable=maybe-no-member
+    kpi_endpoint_id = _create_kpi_request.endpoint_id.endpoint_uuid.uuid # pylint: disable=maybe-no-member
+    kpi_service_id  = _create_kpi_request.service_id.service_uuid.uuid   # pylint: disable=maybe-no-member
+
+    _kpi_id = sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
+    response = sql_db.get_KPI(_kpi_id)
     assert isinstance(response, tuple)
 
-def test_sqlitedb_tools_get_kpis(sql_db):
+def test_sqlitedb_tools_get_kpis(sql_db): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_sqlitedb_tools_get_kpis begin')
     response = sql_db.get_KPIS()
     assert isinstance(response, list)
 
-def test_sqlitedb_tools_delete_kpi(sql_db, create_kpi_request):
+def test_sqlitedb_tools_delete_kpi(sql_db): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_sqlitedb_tools_get_kpi begin')
 
     response = sql_db.delete_KPI("DEV1",KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED)
 
-    if response == False:
-        kpi_description = create_kpi_request.kpi_description
-        kpi_sample_type = create_kpi_request.kpi_sample_type
-        kpi_device_id = create_kpi_request.device_id.device_uuid.uuid
-        kpi_endpoint_id = create_kpi_request.endpoint_id.endpoint_uuid.uuid
-        kpi_service_id = create_kpi_request.service_id.service_uuid.uuid
+    if not response:
+        _create_kpi_request = create_kpi_request()
+        kpi_description = _create_kpi_request.kpi_description                # pylint: disable=maybe-no-member
+        kpi_sample_type = _create_kpi_request.kpi_sample_type                # pylint: disable=maybe-no-member
+        kpi_device_id   = _create_kpi_request.device_id.device_uuid.uuid     # pylint: disable=maybe-no-member
+        kpi_endpoint_id = _create_kpi_request.endpoint_id.endpoint_uuid.uuid # pylint: disable=maybe-no-member
+        kpi_service_id  = _create_kpi_request.service_id.service_uuid.uuid   # pylint: disable=maybe-no-member
 
         sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
         response = sql_db.delete_KPI("DEV1", KpiSampleType.KPISAMPLETYPE_PACKETS_TRANSMITTED)
 
-    assert response == True
+    assert response
 
-def test_sqlitedb_tools_delete_kpid_id(sql_db, create_kpi_request):
+def test_sqlitedb_tools_delete_kpid_id(sql_db): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_sqlitedb_tools_delete_kpid_id begin')
 
     response = sql_db.delete_kpid_id(1)
 
-    if response == False:
-        kpi_description = create_kpi_request.kpi_description
-        kpi_sample_type = create_kpi_request.kpi_sample_type
-        kpi_device_id = create_kpi_request.device_id.device_uuid.uuid
-        kpi_endpoint_id = create_kpi_request.endpoint_id.endpoint_uuid.uuid
-        kpi_service_id = create_kpi_request.service_id.service_uuid.uuid
+    if not response:
+        _create_kpi_request = create_kpi_request()
+        kpi_description = _create_kpi_request.kpi_description                # pylint: disable=maybe-no-member
+        kpi_sample_type = _create_kpi_request.kpi_sample_type                # pylint: disable=maybe-no-member
+        kpi_device_id   = _create_kpi_request.device_id.device_uuid.uuid     # pylint: disable=maybe-no-member
+        kpi_endpoint_id = _create_kpi_request.endpoint_id.endpoint_uuid.uuid # pylint: disable=maybe-no-member
+        kpi_service_id  = _create_kpi_request.service_id.service_uuid.uuid   # pylint: disable=maybe-no-member
 
-        kpi_id = sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
-        response = sql_db.delete_kpid_id(kpi_id)
+        _kpi_id = sql_db.insert_KPI(kpi_description, kpi_sample_type, kpi_device_id, kpi_endpoint_id, kpi_service_id)
+        response = sql_db.delete_kpid_id(_kpi_id)
 
-    assert response == True
+    assert response
 
 
-def test_influxdb_tools_write_kpi(influx_db):
+def test_influxdb_tools_write_kpi(influx_db): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_influxdb_tools_write_kpi begin')
 
-def test_influxdb_tools_read_kpi_points(influx_db):
+def test_influxdb_tools_read_kpi_points(influx_db): # pylint: disable=redefined-outer-name
     LOGGER.warning('test_influxdb_tools_read_kpi_points begin')
 
 
-def test_events_tools(context_client_grpc: ContextClient,  # pylint: disable=redefined-outer-name
-    monitoring_client : MonitoringClient,
-    context_db_mb: Tuple[Database, MessageBroker]):
+def test_events_tools(
+        context_client : ContextClient,                 # pylint: disable=redefined-outer-name
+        device_client : DeviceClient,                   # pylint: disable=redefined-outer-name
+        monitoring_client : MonitoringClient,           # pylint: disable=redefined-outer-name
+        context_db_mb : Tuple[Database, MessageBroker]  # pylint: disable=redefined-outer-name
+    ):
     LOGGER.warning('test_get_device_events begin')
 
     context_database = context_db_mb[0]
@@ -346,10 +321,10 @@ def test_events_tools(context_client_grpc: ContextClient,  # pylint: disable=red
     context_database.clear_all()
 
     # ----- Initialize the EventsCollector -----------------------------------------------------------------------------
-    events_collector = EventsDeviceCollector(context_client_grpc, monitoring_client)
+    events_collector = EventsDeviceCollector()
     events_collector.start()
 
-    # # ----- Dump state of database before create the object ------------------------------------------------------------
+    # ----- Dump state of database before create the object ------------------------------------------------------------
     db_entries = context_database.dump()
     LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
     for db_entry in db_entries:
@@ -357,18 +332,22 @@ def test_events_tools(context_client_grpc: ContextClient,  # pylint: disable=red
     LOGGER.info('-----------------------------------------------------------')
     assert len(db_entries) == 0
 
-    populate('localhost', GRPC_PORT_CONTEXT) # place this call in the appropriate line, according to your tests
-
     # ----- Update the object ------------------------------------------------------------------------------------------
-    response = context_client_grpc.SetDevice(Device(**DEVICE_R1))
-    assert response.device_uuid.uuid == DEVICE_R1_UUID
+    LOGGER.info('Adding Device {:s}'.format(DEVICE_DEV1_UUID))
+    device_with_connect_rules = copy.deepcopy(DEVICE_DEV1)
+    device_with_connect_rules['device_config']['config_rules'].extend(DEVICE_DEV1_CONNECT_RULES)
+    response = device_client.AddDevice(Device(**device_with_connect_rules))
+    assert response.device_uuid.uuid == DEVICE_DEV1_UUID
 
     events_collector.stop()
 
 
-def test_get_device_events(context_client_grpc: ContextClient,  # pylint: disable=redefined-outer-name
-    monitoring_client : MonitoringClient,
-    context_db_mb: Tuple[Database, MessageBroker]):
+def test_get_device_events(
+        context_client : ContextClient,                 # pylint: disable=redefined-outer-name
+        device_client : DeviceClient,                   # pylint: disable=redefined-outer-name
+        monitoring_client : MonitoringClient,           # pylint: disable=redefined-outer-name
+        context_db_mb : Tuple[Database, MessageBroker]  # pylint: disable=redefined-outer-name
+    ):
 
     LOGGER.warning('test_get_device_events begin')
 
@@ -378,10 +357,10 @@ def test_get_device_events(context_client_grpc: ContextClient,  # pylint: disabl
     context_database.clear_all()
 
     # ----- Initialize the EventsCollector -----------------------------------------------------------------------------
-    events_collector = EventsDeviceCollector(context_client_grpc,monitoring_client)
+    events_collector = EventsDeviceCollector()
     events_collector.start()
 
-    # # ----- Dump state of database before create the object ------------------------------------------------------------
+    # ----- Dump state of database before create the object ------------------------------------------------------------
     db_entries = context_database.dump()
     LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
     for db_entry in db_entries:
@@ -389,20 +368,26 @@ def test_get_device_events(context_client_grpc: ContextClient,  # pylint: disabl
     LOGGER.info('-----------------------------------------------------------')
     assert len(db_entries) == 0
 
-    populate('localhost', GRPC_PORT_CONTEXT) # place this call in the appropriate line, according to your tests
-
     # ----- Check create event -----------------------------------------------------------------------------------------
-    event = events_collector.get_event(block=True)
+    LOGGER.info('Adding Device {:s}'.format(DEVICE_DEV1_UUID))
+    device_with_connect_rules = copy.deepcopy(DEVICE_DEV1)
+    device_with_connect_rules['device_config']['config_rules'].extend(DEVICE_DEV1_CONNECT_RULES)
+    response = device_client.AddDevice(Device(**device_with_connect_rules))
+    assert response.device_uuid.uuid == DEVICE_DEV1_UUID
 
+    event = events_collector.get_event(block=True)
     assert isinstance(event, DeviceEvent)
     assert event.event.event_type == EventTypeEnum.EVENTTYPE_CREATE
-    assert event.device_id.device_uuid.uuid == DEVICE_R1_UUID
+    assert event.device_id.device_uuid.uuid == DEVICE_DEV1_UUID
 
     events_collector.stop()
 
-def test_listen_events(monitoring_client: MonitoringClient,
-    context_client_grpc: ContextClient,  # pylint: disable=redefined-outer-name
-    context_db_mb: Tuple[Database, MessageBroker]):
+def test_listen_events(
+        context_client : ContextClient,                 # pylint: disable=redefined-outer-name
+        device_client : DeviceClient,                   # pylint: disable=redefined-outer-name
+        monitoring_client : MonitoringClient,           # pylint: disable=redefined-outer-name
+        context_db_mb : Tuple[Database, MessageBroker]  # pylint: disable=redefined-outer-name
+    ):
 
     LOGGER.warning('test_listen_events begin')
 
@@ -412,10 +397,10 @@ def test_listen_events(monitoring_client: MonitoringClient,
     context_database.clear_all()
 
     # ----- Initialize the EventsCollector -----------------------------------------------------------------------------
-    events_collector = EventsDeviceCollector(context_client_grpc,monitoring_client)
+    events_collector = EventsDeviceCollector()
     events_collector.start()
 
-    # # ----- Dump state of database before create the object ------------------------------------------------------------
+    # ----- Dump state of database before create the object ------------------------------------------------------------
     db_entries = context_database.dump()
     LOGGER.info('----- Database Dump [{:3d} entries] -------------------------'.format(len(db_entries)))
     for db_entry in db_entries:
@@ -423,18 +408,12 @@ def test_listen_events(monitoring_client: MonitoringClient,
     LOGGER.info('-----------------------------------------------------------')
     assert len(db_entries) == 0
 
-    populate('localhost', GRPC_PORT_CONTEXT) # place this call in the appropriate line, according to your tests
+    LOGGER.info('Adding Device {:s}'.format(DEVICE_DEV1_UUID))
+    device_with_connect_rules = copy.deepcopy(DEVICE_DEV1)
+    device_with_connect_rules['device_config']['config_rules'].extend(DEVICE_DEV1_CONNECT_RULES)
+    response = device_client.AddDevice(Device(**device_with_connect_rules))
+    assert response.device_uuid.uuid == DEVICE_DEV1_UUID
 
     kpi_id_list = events_collector.listen_events()
 
-    assert bool(kpi_id_list) == True
-
-def test_socket_ports(address, port):
-    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-    result = s.connect_ex((address,port))
-
-    if result == 0:
-        print('socket is open')
-    else:
-        print('socket is not open')
-    s.close()
+    assert len(kpi_id_list) > 0
-- 
GitLab


From 4d126f2cb5ca082ad16ebc862de6f2c95224fb11 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Fri, 20 May 2022 13:20:35 +0200
Subject: [PATCH 34/60] Multiple changes:

- corrected unitary test file for device component
- arranged clients used by optical centralized attack detector
- Minor corrections in unitary test of Context component
- corrected skeleton for unitary tests of Slice component
---
 scripts/run_tests_locally.sh                  |  2 +-
 src/context/tests/test_unitary.py             |  6 ++--
 ...alizedAttackDetectorServiceServicerImpl.py | 22 +++++++--------
 src/slice/tests/test_unitary.py               | 28 +++++++++----------
 4 files changed, 28 insertions(+), 30 deletions(-)

diff --git a/scripts/run_tests_locally.sh b/scripts/run_tests_locally.sh
index 633510a54..4a95fd8be 100755
--- a/scripts/run_tests_locally.sh
+++ b/scripts/run_tests_locally.sh
@@ -63,7 +63,7 @@ coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
     context/tests/test_unitary.py
 
 coverage run --rcfile=$RCFILE --append -m pytest --log-level=INFO --verbose \
-    device/tests/test_unitary.py
+    device/tests/test_unitary_emulated.py
 
 coverage run --rcfile=$RCFILE --append -m pytest -s --log-level=INFO --verbose \
     l3_centralizedattackdetector/tests/test_unitary.py
diff --git a/src/context/tests/test_unitary.py b/src/context/tests/test_unitary.py
index 870067d1e..0705477ae 100644
--- a/src/context/tests/test_unitary.py
+++ b/src/context/tests/test_unitary.py
@@ -51,9 +51,9 @@ LOCAL_HOST = '127.0.0.1'
 GRPC_PORT = 10000 + get_service_port_grpc(ServiceNameEnum.CONTEXT)   # avoid privileged ports
 HTTP_PORT = 10000 + get_service_port_http(ServiceNameEnum.CONTEXT)   # avoid privileged ports
 
-os.environ[get_env_var_name(ServiceNameEnum.CONTEXT.value, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
-os.environ[get_env_var_name(ServiceNameEnum.CONTEXT.value, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(GRPC_PORT)
-os.environ[get_env_var_name(ServiceNameEnum.CONTEXT.value, ENVVAR_SUFIX_SERVICE_PORT_HTTP)] = str(HTTP_PORT)
+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)
 
 DEFAULT_REDIS_SERVICE_HOST = LOCAL_HOST
 DEFAULT_REDIS_SERVICE_PORT = 6379
diff --git a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py
index f27441e48..d4c71476f 100644
--- a/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py
+++ b/src/opticalcentralizedattackdetector/service/OpticalCentralizedAttackDetectorServiceServicerImpl.py
@@ -16,11 +16,8 @@ import os, grpc, logging, random
 from influxdb import InfluxDBClient
 from common.rpc_method_wrapper.Decorator import create_metrics, safe_and_metered_rpc_method
 from context.client.ContextClient import ContextClient
-from context.Config import GRPC_SERVICE_PORT as CONTEXT_GRPC_SERVICE_PORT
 from monitoring.client.MonitoringClient import MonitoringClient
-from monitoring.Config import GRPC_SERVICE_PORT as MONITORING_GRPC_SERVICE_PORT
 from service.client.ServiceClient import ServiceClient
-from service.Config import GRPC_SERVICE_PORT as SERVICE_GRPC_SERVICE_PORT
 from dbscanserving.proto.dbscanserving_pb2 import DetectionRequest, DetectionResponse, Sample
 from dbscanserving.client.DbscanServingClient import DbscanServingClient
 from dbscanserving.Config import GRPC_SERVICE_PORT as DBSCANSERVING_GRPC_SERVICE_PORT
@@ -35,8 +32,7 @@ from opticalcentralizedattackdetector.proto.monitoring_pb2 import KpiList
 from opticalcentralizedattackdetector.proto.optical_centralized_attack_detector_pb2_grpc import (
     OpticalCentralizedAttackDetectorServiceServicer)
 from opticalcentralizedattackdetector.Config import (
-    CONTEXT_SERVICE_ADDRESS, SERVICE_SERVICE_ADDRESS, INFERENCE_SERVICE_ADDRESS, MONITORING_SERVICE_ADDRESS,
-    ATTACK_MITIGATOR_SERVICE_ADDRESS)
+    INFERENCE_SERVICE_ADDRESS, MONITORING_SERVICE_ADDRESS, ATTACK_MITIGATOR_SERVICE_ADDRESS)
 
 
 LOGGER = logging.getLogger(__name__)
@@ -49,12 +45,16 @@ INFLUXDB_HOSTNAME = os.environ.get("INFLUXDB_HOSTNAME")
 INFLUXDB_USER = os.environ.get("INFLUXDB_USER")
 INFLUXDB_PASSWORD = os.environ.get("INFLUXDB_PASSWORD")
 INFLUXDB_DATABASE = os.environ.get("INFLUXDB_DATABASE")
-context_client: ContextClient = ContextClient(address=CONTEXT_SERVICE_ADDRESS, port=CONTEXT_GRPC_SERVICE_PORT)
-influxdb_client: InfluxDBClient = InfluxDBClient(host=MONITORING_SERVICE_ADDRESS, port=8086, username=INFLUXDB_USER, password=INFLUXDB_PASSWORD, database=INFLUXDB_DATABASE)
-monitoring_client: MonitoringClient = MonitoringClient(server=MONITORING_SERVICE_ADDRESS, port=MONITORING_GRPC_SERVICE_PORT)
-dbscanserving_client: DbscanServingClient = DbscanServingClient(address=INFERENCE_SERVICE_ADDRESS, port=DBSCANSERVING_GRPC_SERVICE_PORT)
-service_client: ServiceClient = ServiceClient(SERVICE_SERVICE_ADDRESS, SERVICE_GRPC_SERVICE_PORT)
-attack_mitigator_client: OpticalAttackMitigatorClient = OpticalAttackMitigatorClient(address=ATTACK_MITIGATOR_SERVICE_ADDRESS, port=ATTACK_MITIGATOR_GRPC_SERVICE_PORT)
+context_client: ContextClient = ContextClient()
+influxdb_client: InfluxDBClient = InfluxDBClient(
+    host=MONITORING_SERVICE_ADDRESS, port=8086, username=INFLUXDB_USER, password=INFLUXDB_PASSWORD,
+    database=INFLUXDB_DATABASE)
+monitoring_client: MonitoringClient = MonitoringClient()
+dbscanserving_client: DbscanServingClient = DbscanServingClient(
+    address=INFERENCE_SERVICE_ADDRESS, port=DBSCANSERVING_GRPC_SERVICE_PORT)
+service_client: ServiceClient = ServiceClient()
+attack_mitigator_client: OpticalAttackMitigatorClient = OpticalAttackMitigatorClient(
+    address=ATTACK_MITIGATOR_SERVICE_ADDRESS, port=ATTACK_MITIGATOR_GRPC_SERVICE_PORT)
 
 
 class OpticalCentralizedAttackDetectorServiceServicerImpl(OpticalCentralizedAttackDetectorServiceServicer):
diff --git a/src/slice/tests/test_unitary.py b/src/slice/tests/test_unitary.py
index fb58b5153..1fd5a75b4 100644
--- a/src/slice/tests/test_unitary.py
+++ b/src/slice/tests/test_unitary.py
@@ -12,34 +12,32 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-import copy, grpc, logging, pytest
-from common.database.Factory import get_database, DatabaseEngineEnum
+import logging, os, pytest
+from common.Constants import ServiceNameEnum
+from common.Settings import (
+    ENVVAR_SUFIX_SERVICE_HOST, ENVVAR_SUFIX_SERVICE_PORT_GRPC, get_env_var_name, get_service_port_grpc)
 from slice.client.SliceClient import SliceClient
-from slice.proto.slice_pb2 import TransportSlice
 from slice.service.SliceService import SliceService
-from slice.Config import GRPC_SERVICE_PORT, GRPC_MAX_WORKERS, GRPC_GRACE_PERIOD
 
-port = 10000 + GRPC_SERVICE_PORT # avoid privileged ports
+LOCAL_HOST = '127.0.0.1'
+MOCKSERVICE_PORT = 10000
+SLICE_SERVICE_PORT = MOCKSERVICE_PORT + get_service_port_grpc(ServiceNameEnum.SLICE) # avoid privileged ports
+os.environ[get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_HOST     )] = str(LOCAL_HOST)
+os.environ[get_env_var_name(ServiceNameEnum.SLICE, ENVVAR_SUFIX_SERVICE_PORT_GRPC)] = str(SLICE_SERVICE_PORT)
 
 LOGGER = logging.getLogger(__name__)
 LOGGER.setLevel(logging.DEBUG)
 
 @pytest.fixture(scope='session')
-def slice_database():
-    _database = get_database(engine=DatabaseEngineEnum.INMEMORY)
-    return _database
-
-@pytest.fixture(scope='session')
-def slice_service(slice_database):
-    _service = SliceService(
-        slice_database, port=port, max_workers=GRPC_MAX_WORKERS, grace_period=GRPC_GRACE_PERIOD)
+def slice_service():
+    _service = SliceService()
     _service.start()
     yield _service
     _service.stop()
 
 @pytest.fixture(scope='session')
-def slice_client(slice_service):
-    _client = SliceClient(address='127.0.0.1', port=port)
+def slice_client(slice_service : SliceService): # pylint: disable=redefined-outer-name
+    _client = SliceClient()
     yield _client
     _client.close()
 
-- 
GitLab


From a55cf1aaeeb8cda68069a16f179a76ff2b8e6369 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Fri, 20 May 2022 13:29:13 +0200
Subject: [PATCH 35/60] Device component: - Corrected unitary test to execute
 pipeline

---
 src/device/.gitlab-ci.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/device/.gitlab-ci.yml b/src/device/.gitlab-ci.yml
index 90f00f7a1..4e337f37e 100644
--- a/src/device/.gitlab-ci.yml
+++ b/src/device/.gitlab-ci.yml
@@ -54,7 +54,7 @@ unit test device:
     - sleep 5
     - docker ps -a
     - docker logs $IMAGE_NAME
-    - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
+    - docker exec -i $IMAGE_NAME bash -c "coverage run -m pytest --log-level=INFO --verbose $IMAGE_NAME/tests/test_unitary_emulated.py --junitxml=/opt/results/${IMAGE_NAME}_report.xml"
     - docker exec -i $IMAGE_NAME bash -c "coverage report --include='${IMAGE_NAME}/*' --show-missing"
   coverage: '/TOTAL\s+\d+\s+\d+\s+(\d+%)/'
   after_script:
-- 
GitLab


From 6d85ebdca97ccbe2487a67a7a6811a02ee5c4b26 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Fri, 20 May 2022 13:48:19 +0200
Subject: [PATCH 36/60] Monitoring component: - added missing dependency for
 unitary tests

---
 src/monitoring/Dockerfile | 6 +-----
 1 file changed, 1 insertion(+), 5 deletions(-)

diff --git a/src/monitoring/Dockerfile b/src/monitoring/Dockerfile
index c1bba549e..ca18929f1 100644
--- a/src/monitoring/Dockerfile
+++ b/src/monitoring/Dockerfile
@@ -39,8 +39,6 @@ RUN mkdir -p /var/teraflow/common
 RUN mkdir -p /var/teraflow/common/tools
 RUN mkdir -p /var/teraflow/common/rpc_method_wrapper
 RUN mkdir -p /var/teraflow/device
-RUN mkdir -p /var/teraflow/device/proto
-RUN mkdir -p /var/teraflow/device/client
 RUN mkdir -p /var/teraflow/context
 
 # Get Python packages per module
@@ -50,11 +48,9 @@ RUN python3 -m pip install -r requirements.txt
 
 # add files into working directory
 COPY monitoring/. monitoring
-COPY device/proto/. device/proto
-COPY device/client/. device/client
-COPY device/Config.py device
 COPY common/. common
 COPY context/. context
+COPY device/. device
 
 RUN rm -r common/message_broker/tests
 RUN rm -r common/orm/tests
-- 
GitLab


From ea44222a057c2e1e45b5eb709f1f3c28df9a02c8 Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Fri, 20 May 2022 13:57:41 +0200
Subject: [PATCH 37/60] Updated Monitoring requirements

---
 src/monitoring/requirements.in | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/monitoring/requirements.in b/src/monitoring/requirements.in
index 839ea33af..4d4f057bd 100644
--- a/src/monitoring/requirements.in
+++ b/src/monitoring/requirements.in
@@ -1,17 +1,25 @@
-#google-api-core
+anytree==2.8.0
+APScheduler==3.8.1
+fastcache==1.1.0
 grpcio==1.43.0
 grpcio-health-checking==1.43.0
+#google-api-core
 #opencensus[stackdriver]
-python-json-logger
 #google-cloud-profiler
 #numpy
+Jinja2==3.0.3
+ncclient==0.6.13
+p4runtime==1.3.0
+paramiko==2.9.2
 prometheus-client==0.13.0
 protobuf==3.19.3
 pytest==6.2.5
 pytest-benchmark==3.4.1
 influxdb
+python-dateutil==2.8.2
+python-json-logger==2.0.2
+pytz==2021.3
 redis==4.1.2
-#anytree==2.8.0
-#APScheduler==3.8.1
-#xmltodict==0.12.0
+requests==2.27.1
+xmltodict==0.12.0
 coverage==6.3
-- 
GitLab


From ed91fd7abad1a7cc656eb6f4dbf6bc7647f9dfb6 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Mon, 23 May 2022 13:49:51 +0300
Subject: [PATCH 38/60] ci(policy): refactor gitlab-ci.yml

---
 src/policy/.gitlab-ci.yml | 58 ++++++++++++++++++++++++++++-----------
 1 file changed, 42 insertions(+), 16 deletions(-)

diff --git a/src/policy/.gitlab-ci.yml b/src/policy/.gitlab-ci.yml
index 1f855bb18..164540a05 100644
--- a/src/policy/.gitlab-ci.yml
+++ b/src/policy/.gitlab-ci.yml
@@ -12,45 +12,71 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
+variables:
+  IMAGE_NAME_POLICY: 'policy'
+  REPORTS_PATH_POLICY: "src/${IMAGE_NAME_POLICY}/reports"
+  BUILD_ENV_POLICY: build-policy.env
+
 # Package application needed to run tests & build the image on next stage
 build policy:
-  variables:
-    IMAGE_NAME: 'policy' # name of the microservice
-    IMAGE_NAME_TEST: 'policy-test' # name of the microservice
-    IMAGE_TAG: '0.1.0' # tag of the container image (production, development, etc)
   stage: build
   script:
-    - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/src/main/docker/Dockerfile.multistage.jvm ./src/$IMAGE_NAME/ --target builder
+    - export IMAGE_TAG=$(grep -m1 '<version>' ./src/$IMAGE_NAME_POLICY/pom.xml | grep -oP  '(?<=>).*(?=<)')
+    - echo "IMAGE_TAG=${IMAGE_TAG}" >> ${BUILD_ENV_POLICY}
+    - cat ${BUILD_ENV_POLICY}
+    - docker build -t "$IMAGE_NAME_POLICY:$IMAGE_TAG" -f ./src/$IMAGE_NAME_POLICY/src/main/docker/Dockerfile.multistage.jvm ./src/$IMAGE_NAME_POLICY/ --target builder
+  after_script:
+    - docker images --filter="dangling=true" --quiet | xargs -r docker rmi
+  artifacts:
+    reports:
+      dotenv: ${BUILD_ENV_POLICY}
   rules:
     - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
     - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
     - changes:
-        - src/$IMAGE_NAME/**
-        - manifests/${IMAGE_NAME}service.yaml
+        - src/$IMAGE_NAME_POLICY/**
+        - manifests/${IMAGE_NAME_POLICY}service.yaml
         - .gitlab-ci.yml
 
 # Run tests, build & push the image
 unit_test policy:
   variables:
-    IMAGE_NAME: 'policy' # name of the microservice
-    IMAGE_NAME_TEST: 'policy-test' # name of the microservice
-    IMAGE_TAG: '0.1.0' # tag of the container image (production, development, etc)
+    REPORTS_CONTAINER: "${IMAGE_NAME_POLICY}-reports"
   stage: unit_test
   needs:
     - build policy
   before_script:
     - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
+    - docker rm ${REPORTS_CONTAINER} || true
   script:
-    - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/src/main/docker/Dockerfile.multistage.jvm ./src/$IMAGE_NAME/ --target unit-test
-    - docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/src/main/docker/Dockerfile.multistage.jvm ./src/$IMAGE_NAME/ --target release
-    - docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
-    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
+    - echo "Running tests for image ${IMAGE_TAG}"
+    - docker build -t "$IMAGE_NAME_POLICY:$IMAGE_TAG" -f ./src/$IMAGE_NAME_POLICY/src/main/docker/Dockerfile.multistage.jvm ./src/$IMAGE_NAME_POLICY/ --target unit-test
+    # Transfer JaCoCo and Surefire reports from within tests image
+    - docker create --name ${REPORTS_CONTAINER} "$IMAGE_NAME_POLICY:$IMAGE_TAG"
+    - mkdir -p ${REPORTS_PATH_POLICY}
+    - docker cp ${REPORTS_CONTAINER}:/app/target/site/jacoco/index.html ${REPORTS_PATH_POLICY}/coverage.html
+    - docker cp ${REPORTS_CONTAINER}:/app/target/site/jacoco/jacoco.xml ${REPORTS_PATH_POLICY}/jacoco.xml
+    - docker cp ${REPORTS_CONTAINER}:/app/target/surefire-reports/ ${REPORTS_PATH_POLICY}/
+    - cat ${REPORTS_PATH_POLICY}/coverage.html | grep -o 'Total[^%]*%' | sed 's/<.*>/ /; s/Total/JaCoCo Coverage Total:/'
+    - docker run -v "$(pwd)/src/${IMAGE_NAME_POLICY}:/${IMAGE_NAME_POLICY}" --rm registry.gitlab.com/haynes/jacoco2cobertura:1.0.7 python /opt/cover2cover.py ${IMAGE_NAME_POLICY}/reports/jacoco.xml ${IMAGE_NAME_POLICY}/src/main/java > ${REPORTS_PATH_POLICY}/cobertura.xml
+    # Build final image
+    - docker build -t "$IMAGE_NAME_POLICY:$IMAGE_TAG" -f ./src/$IMAGE_NAME_POLICY/src/main/docker/Dockerfile.multistage.jvm ./src/$IMAGE_NAME_POLICY/ --target release
+    - docker tag "$IMAGE_NAME_POLICY:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME_POLICY:$IMAGE_TAG"
+    - docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME_POLICY:$IMAGE_TAG"
+  after_script:
+    - docker rm ${REPORTS_CONTAINER}
+    - docker rm -f "$IMAGE_NAME_POLICY:$IMAGE_TAG"
+  coverage: '/JaCoCo Coverage Total: ([0-9]{1,3})%/'
+  artifacts:
+    reports:
+      junit:
+        - ${REPORTS_PATH_POLICY}/surefire-reports/TEST-*.xml
   rules:
     - if: '$CI_PIPELINE_SOURCE == "merge_request_event" && ($CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "develop" || $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH)'
     - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "develop"'
     - changes:
-        - src/$IMAGE_NAME/**
-        - manifests/${IMAGE_NAME}service.yaml
+        - src/$IMAGE_NAME_POLICY/**
+        - manifests/${IMAGE_NAME_POLICY}service.yaml
         - .gitlab-ci.yml
 
 # Deployment of policy service in Kubernetes Cluster
-- 
GitLab


From 2672cdde22434d9eb453942fa1409b9ede7cd758 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Mon, 23 May 2022 14:11:58 +0300
Subject: [PATCH 39/60] chore(policy): update application.yml

---
 src/policy/src/main/resources/application.yml |   14 +-
 .../main/resources/teraflow-policy-banner.txt |    9 +
 .../grpc/context/ContextOuterClass.java       | 6714 ++++++++++++++++-
 .../grpc/context/ContextService.java          |   12 +
 .../grpc/context/ContextServiceBean.java      |   49 +
 .../grpc/context/ContextServiceClient.java    |   25 +
 .../grpc/context/ContextServiceGrpc.java      |  449 +-
 .../context/MutinyContextServiceGrpc.java     |  156 +-
 src/policy/target/kubernetes/kubernetes.yml   |   32 +-
 9 files changed, 7225 insertions(+), 235 deletions(-)
 create mode 100644 src/policy/src/main/resources/teraflow-policy-banner.txt

diff --git a/src/policy/src/main/resources/application.yml b/src/policy/src/main/resources/application.yml
index 2a5a96ccc..2e09b2302 100644
--- a/src/policy/src/main/resources/application.yml
+++ b/src/policy/src/main/resources/application.yml
@@ -13,28 +13,32 @@
 # limitations under the License.
 
 quarkus:
+  banner:
+    path: teraflow-policy-banner.txt
   grpc:
     server:
       port: 9999
       enable-reflection-service: true
   http:
     port: 8080
+
   container-image:
     group: teraflow-h2020
     name: controller/policy
     registry: registry.gitlab.com
+
   kubernetes:
     name: policyservice
     image-pull-policy: Always
-    add-version-to-label-selectors: false
     labels:
       app: policyservice
+    add-version-to-label-selectors: false
     readiness-probe:
-      initial-delay: 5s
-      period: 45s
+      initial-delay: 2s
+      period: 10s
     liveness-probe:
-      initial-delay: 5s
-      period: 45s
+      initial-delay: 2s
+      period: 10s
     ports:
       http:
         host-port: 8080
diff --git a/src/policy/src/main/resources/teraflow-policy-banner.txt b/src/policy/src/main/resources/teraflow-policy-banner.txt
new file mode 100644
index 000000000..d5effd98e
--- /dev/null
+++ b/src/policy/src/main/resources/teraflow-policy-banner.txt
@@ -0,0 +1,9 @@
+
+  _______             ______ _                 _____      _ _
+ |__   __|           |  ____| |               |  __ \    | (_)
+    | | ___ _ __ __ _| |__  | | _____      __ | |__) |__ | |_  ___ _   _
+    | |/ _ \ '__/ _` |  __| | |/ _ \ \ /\ / / |  ___/ _ \| | |/ __| | | |
+    | |  __/ | | (_| | |    | | (_) \ V  V /  | |  | (_) | | | (__| |_| |
+    |_|\___|_|  \__,_|_|    |_|\___/ \_/\_/   |_|   \___/|_|_|\___|\__, |
+                                                                    __/ |
+                                                                   |___/
diff --git a/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java b/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java
index 168ddf78b..ee807d7a7 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextOuterClass.java
@@ -661,6 +661,141 @@ public final class ContextOuterClass {
     // @@protoc_insertion_point(enum_scope:context.ServiceStatusEnum)
   }
 
+  /**
+   * Protobuf enum {@code context.SliceStatusEnum}
+   */
+  public enum SliceStatusEnum
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <code>SLICESTATUS_UNDEFINED = 0;</code>
+     */
+    SLICESTATUS_UNDEFINED(0),
+    /**
+     * <code>SLICESTATUS_PLANNED = 1;</code>
+     */
+    SLICESTATUS_PLANNED(1),
+    /**
+     * <code>SLICESTATUS_INIT = 2;</code>
+     */
+    SLICESTATUS_INIT(2),
+    /**
+     * <code>SLICESTATUS_ACTIVE = 3;</code>
+     */
+    SLICESTATUS_ACTIVE(3),
+    /**
+     * <code>SLICESTATUS_DEINIT = 4;</code>
+     */
+    SLICESTATUS_DEINIT(4),
+    UNRECOGNIZED(-1),
+    ;
+
+    /**
+     * <code>SLICESTATUS_UNDEFINED = 0;</code>
+     */
+    public static final int SLICESTATUS_UNDEFINED_VALUE = 0;
+    /**
+     * <code>SLICESTATUS_PLANNED = 1;</code>
+     */
+    public static final int SLICESTATUS_PLANNED_VALUE = 1;
+    /**
+     * <code>SLICESTATUS_INIT = 2;</code>
+     */
+    public static final int SLICESTATUS_INIT_VALUE = 2;
+    /**
+     * <code>SLICESTATUS_ACTIVE = 3;</code>
+     */
+    public static final int SLICESTATUS_ACTIVE_VALUE = 3;
+    /**
+     * <code>SLICESTATUS_DEINIT = 4;</code>
+     */
+    public static final int SLICESTATUS_DEINIT_VALUE = 4;
+
+
+    public final int getNumber() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     * @deprecated Use {@link #forNumber(int)} instead.
+     */
+    @java.lang.Deprecated
+    public static SliceStatusEnum valueOf(int value) {
+      return forNumber(value);
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     */
+    public static SliceStatusEnum forNumber(int value) {
+      switch (value) {
+        case 0: return SLICESTATUS_UNDEFINED;
+        case 1: return SLICESTATUS_PLANNED;
+        case 2: return SLICESTATUS_INIT;
+        case 3: return SLICESTATUS_ACTIVE;
+        case 4: return SLICESTATUS_DEINIT;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<SliceStatusEnum>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        SliceStatusEnum> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<SliceStatusEnum>() {
+            public SliceStatusEnum findValueByNumber(int number) {
+              return SliceStatusEnum.forNumber(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalStateException(
+            "Can't get the descriptor of an unrecognized enum value.");
+      }
+      return getDescriptor().getValues().get(ordinal());
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return context.ContextOuterClass.getDescriptor().getEnumTypes().get(5);
+    }
+
+    private static final SliceStatusEnum[] VALUES = values();
+
+    public static SliceStatusEnum valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int value;
+
+    private SliceStatusEnum(int value) {
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:context.SliceStatusEnum)
+  }
+
   /**
    * <pre>
    * ----- Configuration -------------------------------------------------------------------------------------------------
@@ -756,7 +891,7 @@ public final class ContextOuterClass {
     }
     public static final com.google.protobuf.Descriptors.EnumDescriptor
         getDescriptor() {
-      return context.ContextOuterClass.getDescriptor().getEnumTypes().get(5);
+      return context.ContextOuterClass.getDescriptor().getEnumTypes().get(6);
     }
 
     private static final ConfigActionEnum[] VALUES = values();
@@ -27653,49 +27788,64 @@ public final class ContextOuterClass {
 
   }
 
-  public interface ConnectionIdOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:context.ConnectionId)
+  public interface SliceIdOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceId)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
-     * @return Whether the connectionUuid field is set.
+     * <code>.context.ContextId context_id = 1;</code>
+     * @return Whether the contextId field is set.
      */
-    boolean hasConnectionUuid();
+    boolean hasContextId();
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
-     * @return The connectionUuid.
+     * <code>.context.ContextId context_id = 1;</code>
+     * @return The contextId.
      */
-    context.ContextOuterClass.Uuid getConnectionUuid();
+    context.ContextOuterClass.ContextId getContextId();
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
+     * <code>.context.ContextId context_id = 1;</code>
      */
-    context.ContextOuterClass.UuidOrBuilder getConnectionUuidOrBuilder();
+    context.ContextOuterClass.ContextIdOrBuilder getContextIdOrBuilder();
+
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     * @return Whether the sliceUuid field is set.
+     */
+    boolean hasSliceUuid();
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     * @return The sliceUuid.
+     */
+    context.ContextOuterClass.Uuid getSliceUuid();
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     */
+    context.ContextOuterClass.UuidOrBuilder getSliceUuidOrBuilder();
   }
   /**
    * <pre>
-   * ----- Connection ----------------------------------------------------------------------------------------------------
+   * ----- Slice ---------------------------------------------------------------------------------------------------------
    * </pre>
    *
-   * Protobuf type {@code context.ConnectionId}
+   * Protobuf type {@code context.SliceId}
    */
-  public static final class ConnectionId extends
+  public static final class SliceId extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:context.ConnectionId)
-      ConnectionIdOrBuilder {
+      // @@protoc_insertion_point(message_implements:context.SliceId)
+      SliceIdOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use ConnectionId.newBuilder() to construct.
-    private ConnectionId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SliceId.newBuilder() to construct.
+    private SliceId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private ConnectionId() {
+    private SliceId() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new ConnectionId();
+      return new SliceId();
     }
 
     @java.lang.Override
@@ -27703,7 +27853,7 @@ public final class ContextOuterClass {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private ConnectionId(
+    private SliceId(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -27722,14 +27872,27 @@ public final class ContextOuterClass {
               done = true;
               break;
             case 10: {
+              context.ContextOuterClass.ContextId.Builder subBuilder = null;
+              if (contextId_ != null) {
+                subBuilder = contextId_.toBuilder();
+              }
+              contextId_ = input.readMessage(context.ContextOuterClass.ContextId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(contextId_);
+                contextId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
               context.ContextOuterClass.Uuid.Builder subBuilder = null;
-              if (connectionUuid_ != null) {
-                subBuilder = connectionUuid_.toBuilder();
+              if (sliceUuid_ != null) {
+                subBuilder = sliceUuid_.toBuilder();
               }
-              connectionUuid_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              sliceUuid_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(connectionUuid_);
-                connectionUuid_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(sliceUuid_);
+                sliceUuid_ = subBuilder.buildPartial();
               }
 
               break;
@@ -27755,41 +27918,67 @@ public final class ContextOuterClass {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+      return context.ContextOuterClass.internal_static_context_SliceId_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return context.ContextOuterClass.internal_static_context_ConnectionId_fieldAccessorTable
+      return context.ContextOuterClass.internal_static_context_SliceId_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              context.ContextOuterClass.ConnectionId.class, context.ContextOuterClass.ConnectionId.Builder.class);
+              context.ContextOuterClass.SliceId.class, context.ContextOuterClass.SliceId.Builder.class);
     }
 
-    public static final int CONNECTION_UUID_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Uuid connectionUuid_;
+    public static final int CONTEXT_ID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.ContextId contextId_;
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
-     * @return Whether the connectionUuid field is set.
+     * <code>.context.ContextId context_id = 1;</code>
+     * @return Whether the contextId field is set.
      */
     @java.lang.Override
-    public boolean hasConnectionUuid() {
-      return connectionUuid_ != null;
+    public boolean hasContextId() {
+      return contextId_ != null;
     }
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
-     * @return The connectionUuid.
+     * <code>.context.ContextId context_id = 1;</code>
+     * @return The contextId.
      */
     @java.lang.Override
-    public context.ContextOuterClass.Uuid getConnectionUuid() {
-      return connectionUuid_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : connectionUuid_;
+    public context.ContextOuterClass.ContextId getContextId() {
+      return contextId_ == null ? context.ContextOuterClass.ContextId.getDefaultInstance() : contextId_;
     }
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
+     * <code>.context.ContextId context_id = 1;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.UuidOrBuilder getConnectionUuidOrBuilder() {
-      return getConnectionUuid();
+    public context.ContextOuterClass.ContextIdOrBuilder getContextIdOrBuilder() {
+      return getContextId();
+    }
+
+    public static final int SLICE_UUID_FIELD_NUMBER = 2;
+    private context.ContextOuterClass.Uuid sliceUuid_;
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     * @return Whether the sliceUuid field is set.
+     */
+    @java.lang.Override
+    public boolean hasSliceUuid() {
+      return sliceUuid_ != null;
+    }
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     * @return The sliceUuid.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Uuid getSliceUuid() {
+      return sliceUuid_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : sliceUuid_;
+    }
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.UuidOrBuilder getSliceUuidOrBuilder() {
+      return getSliceUuid();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -27806,8 +27995,11 @@ public final class ContextOuterClass {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (connectionUuid_ != null) {
-        output.writeMessage(1, getConnectionUuid());
+      if (contextId_ != null) {
+        output.writeMessage(1, getContextId());
+      }
+      if (sliceUuid_ != null) {
+        output.writeMessage(2, getSliceUuid());
       }
       unknownFields.writeTo(output);
     }
@@ -27818,9 +28010,13 @@ public final class ContextOuterClass {
       if (size != -1) return size;
 
       size = 0;
-      if (connectionUuid_ != null) {
+      if (contextId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getConnectionUuid());
+          .computeMessageSize(1, getContextId());
+      }
+      if (sliceUuid_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getSliceUuid());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -27832,15 +28028,20 @@ public final class ContextOuterClass {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof context.ContextOuterClass.ConnectionId)) {
+      if (!(obj instanceof context.ContextOuterClass.SliceId)) {
         return super.equals(obj);
       }
-      context.ContextOuterClass.ConnectionId other = (context.ContextOuterClass.ConnectionId) obj;
+      context.ContextOuterClass.SliceId other = (context.ContextOuterClass.SliceId) obj;
 
-      if (hasConnectionUuid() != other.hasConnectionUuid()) return false;
-      if (hasConnectionUuid()) {
-        if (!getConnectionUuid()
-            .equals(other.getConnectionUuid())) return false;
+      if (hasContextId() != other.hasContextId()) return false;
+      if (hasContextId()) {
+        if (!getContextId()
+            .equals(other.getContextId())) return false;
+      }
+      if (hasSliceUuid() != other.hasSliceUuid()) return false;
+      if (hasSliceUuid()) {
+        if (!getSliceUuid()
+            .equals(other.getSliceUuid())) return false;
       }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
@@ -27853,78 +28054,82 @@ public final class ContextOuterClass {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasConnectionUuid()) {
-        hash = (37 * hash) + CONNECTION_UUID_FIELD_NUMBER;
-        hash = (53 * hash) + getConnectionUuid().hashCode();
+      if (hasContextId()) {
+        hash = (37 * hash) + CONTEXT_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getContextId().hashCode();
+      }
+      if (hasSliceUuid()) {
+        hash = (37 * hash) + SLICE_UUID_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceUuid().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(byte[] data)
+    public static context.ContextOuterClass.SliceId parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(java.io.InputStream input)
+    public static context.ContextOuterClass.SliceId parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseDelimitedFrom(java.io.InputStream input)
+    public static context.ContextOuterClass.SliceId parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static context.ContextOuterClass.ConnectionId parseDelimitedFrom(
+    public static context.ContextOuterClass.SliceId parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -27937,7 +28142,7 @@ public final class ContextOuterClass {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(context.ContextOuterClass.ConnectionId prototype) {
+    public static Builder newBuilder(context.ContextOuterClass.SliceId prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -27954,29 +28159,29 @@ public final class ContextOuterClass {
     }
     /**
      * <pre>
-     * ----- Connection ----------------------------------------------------------------------------------------------------
+     * ----- Slice ---------------------------------------------------------------------------------------------------------
      * </pre>
      *
-     * Protobuf type {@code context.ConnectionId}
+     * Protobuf type {@code context.SliceId}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:context.ConnectionId)
-        context.ContextOuterClass.ConnectionIdOrBuilder {
+        // @@protoc_insertion_point(builder_implements:context.SliceId)
+        context.ContextOuterClass.SliceIdOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+        return context.ContextOuterClass.internal_static_context_SliceId_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return context.ContextOuterClass.internal_static_context_ConnectionId_fieldAccessorTable
+        return context.ContextOuterClass.internal_static_context_SliceId_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                context.ContextOuterClass.ConnectionId.class, context.ContextOuterClass.ConnectionId.Builder.class);
+                context.ContextOuterClass.SliceId.class, context.ContextOuterClass.SliceId.Builder.class);
       }
 
-      // Construct using context.ContextOuterClass.ConnectionId.newBuilder()
+      // Construct using context.ContextOuterClass.SliceId.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -27994,11 +28199,17 @@ public final class ContextOuterClass {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (connectionUuidBuilder_ == null) {
-          connectionUuid_ = null;
+        if (contextIdBuilder_ == null) {
+          contextId_ = null;
         } else {
-          connectionUuid_ = null;
-          connectionUuidBuilder_ = null;
+          contextId_ = null;
+          contextIdBuilder_ = null;
+        }
+        if (sliceUuidBuilder_ == null) {
+          sliceUuid_ = null;
+        } else {
+          sliceUuid_ = null;
+          sliceUuidBuilder_ = null;
         }
         return this;
       }
@@ -28006,17 +28217,17 @@ public final class ContextOuterClass {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+        return context.ContextOuterClass.internal_static_context_SliceId_descriptor;
       }
 
       @java.lang.Override
-      public context.ContextOuterClass.ConnectionId getDefaultInstanceForType() {
-        return context.ContextOuterClass.ConnectionId.getDefaultInstance();
+      public context.ContextOuterClass.SliceId getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceId.getDefaultInstance();
       }
 
       @java.lang.Override
-      public context.ContextOuterClass.ConnectionId build() {
-        context.ContextOuterClass.ConnectionId result = buildPartial();
+      public context.ContextOuterClass.SliceId build() {
+        context.ContextOuterClass.SliceId result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -28024,12 +28235,6018 @@ public final class ContextOuterClass {
       }
 
       @java.lang.Override
-      public context.ContextOuterClass.ConnectionId buildPartial() {
-        context.ContextOuterClass.ConnectionId result = new context.ContextOuterClass.ConnectionId(this);
-        if (connectionUuidBuilder_ == null) {
-          result.connectionUuid_ = connectionUuid_;
+      public context.ContextOuterClass.SliceId buildPartial() {
+        context.ContextOuterClass.SliceId result = new context.ContextOuterClass.SliceId(this);
+        if (contextIdBuilder_ == null) {
+          result.contextId_ = contextId_;
         } else {
-          result.connectionUuid_ = connectionUuidBuilder_.build();
+          result.contextId_ = contextIdBuilder_.build();
+        }
+        if (sliceUuidBuilder_ == null) {
+          result.sliceUuid_ = sliceUuid_;
+        } else {
+          result.sliceUuid_ = sliceUuidBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceId) {
+          return mergeFrom((context.ContextOuterClass.SliceId)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceId other) {
+        if (other == context.ContextOuterClass.SliceId.getDefaultInstance()) return this;
+        if (other.hasContextId()) {
+          mergeContextId(other.getContextId());
+        }
+        if (other.hasSliceUuid()) {
+          mergeSliceUuid(other.getSliceUuid());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceId parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceId) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private context.ContextOuterClass.ContextId contextId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ContextId, context.ContextOuterClass.ContextId.Builder, context.ContextOuterClass.ContextIdOrBuilder> contextIdBuilder_;
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       * @return Whether the contextId field is set.
+       */
+      public boolean hasContextId() {
+        return contextIdBuilder_ != null || contextId_ != null;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       * @return The contextId.
+       */
+      public context.ContextOuterClass.ContextId getContextId() {
+        if (contextIdBuilder_ == null) {
+          return contextId_ == null ? context.ContextOuterClass.ContextId.getDefaultInstance() : contextId_;
+        } else {
+          return contextIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public Builder setContextId(context.ContextOuterClass.ContextId value) {
+        if (contextIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          contextId_ = value;
+          onChanged();
+        } else {
+          contextIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public Builder setContextId(
+          context.ContextOuterClass.ContextId.Builder builderForValue) {
+        if (contextIdBuilder_ == null) {
+          contextId_ = builderForValue.build();
+          onChanged();
+        } else {
+          contextIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public Builder mergeContextId(context.ContextOuterClass.ContextId value) {
+        if (contextIdBuilder_ == null) {
+          if (contextId_ != null) {
+            contextId_ =
+              context.ContextOuterClass.ContextId.newBuilder(contextId_).mergeFrom(value).buildPartial();
+          } else {
+            contextId_ = value;
+          }
+          onChanged();
+        } else {
+          contextIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public Builder clearContextId() {
+        if (contextIdBuilder_ == null) {
+          contextId_ = null;
+          onChanged();
+        } else {
+          contextId_ = null;
+          contextIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public context.ContextOuterClass.ContextId.Builder getContextIdBuilder() {
+        
+        onChanged();
+        return getContextIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public context.ContextOuterClass.ContextIdOrBuilder getContextIdOrBuilder() {
+        if (contextIdBuilder_ != null) {
+          return contextIdBuilder_.getMessageOrBuilder();
+        } else {
+          return contextId_ == null ?
+              context.ContextOuterClass.ContextId.getDefaultInstance() : contextId_;
+        }
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ContextId, context.ContextOuterClass.ContextId.Builder, context.ContextOuterClass.ContextIdOrBuilder> 
+          getContextIdFieldBuilder() {
+        if (contextIdBuilder_ == null) {
+          contextIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.ContextId, context.ContextOuterClass.ContextId.Builder, context.ContextOuterClass.ContextIdOrBuilder>(
+                  getContextId(),
+                  getParentForChildren(),
+                  isClean());
+          contextId_ = null;
+        }
+        return contextIdBuilder_;
+      }
+
+      private context.ContextOuterClass.Uuid sliceUuid_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> sliceUuidBuilder_;
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       * @return Whether the sliceUuid field is set.
+       */
+      public boolean hasSliceUuid() {
+        return sliceUuidBuilder_ != null || sliceUuid_ != null;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       * @return The sliceUuid.
+       */
+      public context.ContextOuterClass.Uuid getSliceUuid() {
+        if (sliceUuidBuilder_ == null) {
+          return sliceUuid_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : sliceUuid_;
+        } else {
+          return sliceUuidBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public Builder setSliceUuid(context.ContextOuterClass.Uuid value) {
+        if (sliceUuidBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          sliceUuid_ = value;
+          onChanged();
+        } else {
+          sliceUuidBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public Builder setSliceUuid(
+          context.ContextOuterClass.Uuid.Builder builderForValue) {
+        if (sliceUuidBuilder_ == null) {
+          sliceUuid_ = builderForValue.build();
+          onChanged();
+        } else {
+          sliceUuidBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public Builder mergeSliceUuid(context.ContextOuterClass.Uuid value) {
+        if (sliceUuidBuilder_ == null) {
+          if (sliceUuid_ != null) {
+            sliceUuid_ =
+              context.ContextOuterClass.Uuid.newBuilder(sliceUuid_).mergeFrom(value).buildPartial();
+          } else {
+            sliceUuid_ = value;
+          }
+          onChanged();
+        } else {
+          sliceUuidBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public Builder clearSliceUuid() {
+        if (sliceUuidBuilder_ == null) {
+          sliceUuid_ = null;
+          onChanged();
+        } else {
+          sliceUuid_ = null;
+          sliceUuidBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public context.ContextOuterClass.Uuid.Builder getSliceUuidBuilder() {
+        
+        onChanged();
+        return getSliceUuidFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public context.ContextOuterClass.UuidOrBuilder getSliceUuidOrBuilder() {
+        if (sliceUuidBuilder_ != null) {
+          return sliceUuidBuilder_.getMessageOrBuilder();
+        } else {
+          return sliceUuid_ == null ?
+              context.ContextOuterClass.Uuid.getDefaultInstance() : sliceUuid_;
+        }
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
+          getSliceUuidFieldBuilder() {
+        if (sliceUuidBuilder_ == null) {
+          sliceUuidBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
+                  getSliceUuid(),
+                  getParentForChildren(),
+                  isClean());
+          sliceUuid_ = null;
+        }
+        return sliceUuidBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceId)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceId)
+    private static final context.ContextOuterClass.SliceId DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceId();
+    }
+
+    public static context.ContextOuterClass.SliceId getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceId>
+        PARSER = new com.google.protobuf.AbstractParser<SliceId>() {
+      @java.lang.Override
+      public SliceId parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceId(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceId> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceId> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.Slice)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     * @return Whether the sliceId field is set.
+     */
+    boolean hasSliceId();
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     * @return The sliceId.
+     */
+    context.ContextOuterClass.SliceId getSliceId();
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     */
+    context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
+
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    java.util.List<context.ContextOuterClass.EndPointId> 
+        getSliceEndpointIdsList();
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    context.ContextOuterClass.EndPointId getSliceEndpointIds(int index);
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    int getSliceEndpointIdsCount();
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.EndPointIdOrBuilder> 
+        getSliceEndpointIdsOrBuilderList();
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    context.ContextOuterClass.EndPointIdOrBuilder getSliceEndpointIdsOrBuilder(
+        int index);
+
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    java.util.List<context.ContextOuterClass.Constraint> 
+        getSliceConstraintsList();
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    context.ContextOuterClass.Constraint getSliceConstraints(int index);
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    int getSliceConstraintsCount();
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.ConstraintOrBuilder> 
+        getSliceConstraintsOrBuilderList();
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    context.ContextOuterClass.ConstraintOrBuilder getSliceConstraintsOrBuilder(
+        int index);
+
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    java.util.List<context.ContextOuterClass.ServiceId> 
+        getSliceServiceIdsList();
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    context.ContextOuterClass.ServiceId getSliceServiceIds(int index);
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    int getSliceServiceIdsCount();
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.ServiceIdOrBuilder> 
+        getSliceServiceIdsOrBuilderList();
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    context.ContextOuterClass.ServiceIdOrBuilder getSliceServiceIdsOrBuilder(
+        int index);
+
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    java.util.List<context.ContextOuterClass.SliceId> 
+        getSliceSubsliceIdsList();
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    context.ContextOuterClass.SliceId getSliceSubsliceIds(int index);
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    int getSliceSubsliceIdsCount();
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+        getSliceSubsliceIdsOrBuilderList();
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    context.ContextOuterClass.SliceIdOrBuilder getSliceSubsliceIdsOrBuilder(
+        int index);
+
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     * @return Whether the sliceStatus field is set.
+     */
+    boolean hasSliceStatus();
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     * @return The sliceStatus.
+     */
+    context.ContextOuterClass.SliceStatus getSliceStatus();
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     */
+    context.ContextOuterClass.SliceStatusOrBuilder getSliceStatusOrBuilder();
+  }
+  /**
+   * Protobuf type {@code context.Slice}
+   */
+  public static final class Slice extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.Slice)
+      SliceOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use Slice.newBuilder() to construct.
+    private Slice(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private Slice() {
+      sliceEndpointIds_ = java.util.Collections.emptyList();
+      sliceConstraints_ = java.util.Collections.emptyList();
+      sliceServiceIds_ = java.util.Collections.emptyList();
+      sliceSubsliceIds_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new Slice();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Slice(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              context.ContextOuterClass.SliceId.Builder subBuilder = null;
+              if (sliceId_ != null) {
+                subBuilder = sliceId_.toBuilder();
+              }
+              sliceId_ = input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(sliceId_);
+                sliceId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                sliceEndpointIds_ = new java.util.ArrayList<context.ContextOuterClass.EndPointId>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              sliceEndpointIds_.add(
+                  input.readMessage(context.ContextOuterClass.EndPointId.parser(), extensionRegistry));
+              break;
+            }
+            case 26: {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+                sliceConstraints_ = new java.util.ArrayList<context.ContextOuterClass.Constraint>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              sliceConstraints_.add(
+                  input.readMessage(context.ContextOuterClass.Constraint.parser(), extensionRegistry));
+              break;
+            }
+            case 34: {
+              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
+                sliceServiceIds_ = new java.util.ArrayList<context.ContextOuterClass.ServiceId>();
+                mutable_bitField0_ |= 0x00000004;
+              }
+              sliceServiceIds_.add(
+                  input.readMessage(context.ContextOuterClass.ServiceId.parser(), extensionRegistry));
+              break;
+            }
+            case 42: {
+              if (!((mutable_bitField0_ & 0x00000008) != 0)) {
+                sliceSubsliceIds_ = new java.util.ArrayList<context.ContextOuterClass.SliceId>();
+                mutable_bitField0_ |= 0x00000008;
+              }
+              sliceSubsliceIds_.add(
+                  input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry));
+              break;
+            }
+            case 50: {
+              context.ContextOuterClass.SliceStatus.Builder subBuilder = null;
+              if (sliceStatus_ != null) {
+                subBuilder = sliceStatus_.toBuilder();
+              }
+              sliceStatus_ = input.readMessage(context.ContextOuterClass.SliceStatus.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(sliceStatus_);
+                sliceStatus_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          sliceEndpointIds_ = java.util.Collections.unmodifiableList(sliceEndpointIds_);
+        }
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
+          sliceConstraints_ = java.util.Collections.unmodifiableList(sliceConstraints_);
+        }
+        if (((mutable_bitField0_ & 0x00000004) != 0)) {
+          sliceServiceIds_ = java.util.Collections.unmodifiableList(sliceServiceIds_);
+        }
+        if (((mutable_bitField0_ & 0x00000008) != 0)) {
+          sliceSubsliceIds_ = java.util.Collections.unmodifiableList(sliceSubsliceIds_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_Slice_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_Slice_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.Slice.class, context.ContextOuterClass.Slice.Builder.class);
+    }
+
+    public static final int SLICE_ID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.SliceId sliceId_;
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     * @return Whether the sliceId field is set.
+     */
+    @java.lang.Override
+    public boolean hasSliceId() {
+      return sliceId_ != null;
+    }
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     * @return The sliceId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getSliceId() {
+      return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+    }
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
+      return getSliceId();
+    }
+
+    public static final int SLICE_ENDPOINT_IDS_FIELD_NUMBER = 2;
+    private java.util.List<context.ContextOuterClass.EndPointId> sliceEndpointIds_;
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.EndPointId> getSliceEndpointIdsList() {
+      return sliceEndpointIds_;
+    }
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.EndPointIdOrBuilder> 
+        getSliceEndpointIdsOrBuilderList() {
+      return sliceEndpointIds_;
+    }
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public int getSliceEndpointIdsCount() {
+      return sliceEndpointIds_.size();
+    }
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.EndPointId getSliceEndpointIds(int index) {
+      return sliceEndpointIds_.get(index);
+    }
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.EndPointIdOrBuilder getSliceEndpointIdsOrBuilder(
+        int index) {
+      return sliceEndpointIds_.get(index);
+    }
+
+    public static final int SLICE_CONSTRAINTS_FIELD_NUMBER = 3;
+    private java.util.List<context.ContextOuterClass.Constraint> sliceConstraints_;
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.Constraint> getSliceConstraintsList() {
+      return sliceConstraints_;
+    }
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.ConstraintOrBuilder> 
+        getSliceConstraintsOrBuilderList() {
+      return sliceConstraints_;
+    }
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public int getSliceConstraintsCount() {
+      return sliceConstraints_.size();
+    }
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Constraint getSliceConstraints(int index) {
+      return sliceConstraints_.get(index);
+    }
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ConstraintOrBuilder getSliceConstraintsOrBuilder(
+        int index) {
+      return sliceConstraints_.get(index);
+    }
+
+    public static final int SLICE_SERVICE_IDS_FIELD_NUMBER = 4;
+    private java.util.List<context.ContextOuterClass.ServiceId> sliceServiceIds_;
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.ServiceId> getSliceServiceIdsList() {
+      return sliceServiceIds_;
+    }
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.ServiceIdOrBuilder> 
+        getSliceServiceIdsOrBuilderList() {
+      return sliceServiceIds_;
+    }
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public int getSliceServiceIdsCount() {
+      return sliceServiceIds_.size();
+    }
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ServiceId getSliceServiceIds(int index) {
+      return sliceServiceIds_.get(index);
+    }
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ServiceIdOrBuilder getSliceServiceIdsOrBuilder(
+        int index) {
+      return sliceServiceIds_.get(index);
+    }
+
+    public static final int SLICE_SUBSLICE_IDS_FIELD_NUMBER = 5;
+    private java.util.List<context.ContextOuterClass.SliceId> sliceSubsliceIds_;
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.SliceId> getSliceSubsliceIdsList() {
+      return sliceSubsliceIds_;
+    }
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+        getSliceSubsliceIdsOrBuilderList() {
+      return sliceSubsliceIds_;
+    }
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public int getSliceSubsliceIdsCount() {
+      return sliceSubsliceIds_.size();
+    }
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getSliceSubsliceIds(int index) {
+      return sliceSubsliceIds_.get(index);
+    }
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdOrBuilder getSliceSubsliceIdsOrBuilder(
+        int index) {
+      return sliceSubsliceIds_.get(index);
+    }
+
+    public static final int SLICE_STATUS_FIELD_NUMBER = 6;
+    private context.ContextOuterClass.SliceStatus sliceStatus_;
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     * @return Whether the sliceStatus field is set.
+     */
+    @java.lang.Override
+    public boolean hasSliceStatus() {
+      return sliceStatus_ != null;
+    }
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     * @return The sliceStatus.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceStatus getSliceStatus() {
+      return sliceStatus_ == null ? context.ContextOuterClass.SliceStatus.getDefaultInstance() : sliceStatus_;
+    }
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceStatusOrBuilder getSliceStatusOrBuilder() {
+      return getSliceStatus();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (sliceId_ != null) {
+        output.writeMessage(1, getSliceId());
+      }
+      for (int i = 0; i < sliceEndpointIds_.size(); i++) {
+        output.writeMessage(2, sliceEndpointIds_.get(i));
+      }
+      for (int i = 0; i < sliceConstraints_.size(); i++) {
+        output.writeMessage(3, sliceConstraints_.get(i));
+      }
+      for (int i = 0; i < sliceServiceIds_.size(); i++) {
+        output.writeMessage(4, sliceServiceIds_.get(i));
+      }
+      for (int i = 0; i < sliceSubsliceIds_.size(); i++) {
+        output.writeMessage(5, sliceSubsliceIds_.get(i));
+      }
+      if (sliceStatus_ != null) {
+        output.writeMessage(6, getSliceStatus());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (sliceId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getSliceId());
+      }
+      for (int i = 0; i < sliceEndpointIds_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, sliceEndpointIds_.get(i));
+      }
+      for (int i = 0; i < sliceConstraints_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, sliceConstraints_.get(i));
+      }
+      for (int i = 0; i < sliceServiceIds_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, sliceServiceIds_.get(i));
+      }
+      for (int i = 0; i < sliceSubsliceIds_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, sliceSubsliceIds_.get(i));
+      }
+      if (sliceStatus_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, getSliceStatus());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.Slice)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.Slice other = (context.ContextOuterClass.Slice) obj;
+
+      if (hasSliceId() != other.hasSliceId()) return false;
+      if (hasSliceId()) {
+        if (!getSliceId()
+            .equals(other.getSliceId())) return false;
+      }
+      if (!getSliceEndpointIdsList()
+          .equals(other.getSliceEndpointIdsList())) return false;
+      if (!getSliceConstraintsList()
+          .equals(other.getSliceConstraintsList())) return false;
+      if (!getSliceServiceIdsList()
+          .equals(other.getSliceServiceIdsList())) return false;
+      if (!getSliceSubsliceIdsList()
+          .equals(other.getSliceSubsliceIdsList())) return false;
+      if (hasSliceStatus() != other.hasSliceStatus()) return false;
+      if (hasSliceStatus()) {
+        if (!getSliceStatus()
+            .equals(other.getSliceStatus())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasSliceId()) {
+        hash = (37 * hash) + SLICE_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceId().hashCode();
+      }
+      if (getSliceEndpointIdsCount() > 0) {
+        hash = (37 * hash) + SLICE_ENDPOINT_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceEndpointIdsList().hashCode();
+      }
+      if (getSliceConstraintsCount() > 0) {
+        hash = (37 * hash) + SLICE_CONSTRAINTS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceConstraintsList().hashCode();
+      }
+      if (getSliceServiceIdsCount() > 0) {
+        hash = (37 * hash) + SLICE_SERVICE_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceServiceIdsList().hashCode();
+      }
+      if (getSliceSubsliceIdsCount() > 0) {
+        hash = (37 * hash) + SLICE_SUBSLICE_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceSubsliceIdsList().hashCode();
+      }
+      if (hasSliceStatus()) {
+        hash = (37 * hash) + SLICE_STATUS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceStatus().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.Slice parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.Slice parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.Slice prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.Slice}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.Slice)
+        context.ContextOuterClass.SliceOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_Slice_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_Slice_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.Slice.class, context.ContextOuterClass.Slice.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.Slice.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getSliceEndpointIdsFieldBuilder();
+          getSliceConstraintsFieldBuilder();
+          getSliceServiceIdsFieldBuilder();
+          getSliceSubsliceIdsFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+        if (sliceEndpointIdsBuilder_ == null) {
+          sliceEndpointIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          sliceEndpointIdsBuilder_.clear();
+        }
+        if (sliceConstraintsBuilder_ == null) {
+          sliceConstraints_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+        } else {
+          sliceConstraintsBuilder_.clear();
+        }
+        if (sliceServiceIdsBuilder_ == null) {
+          sliceServiceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000004);
+        } else {
+          sliceServiceIdsBuilder_.clear();
+        }
+        if (sliceSubsliceIdsBuilder_ == null) {
+          sliceSubsliceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+        } else {
+          sliceSubsliceIdsBuilder_.clear();
+        }
+        if (sliceStatusBuilder_ == null) {
+          sliceStatus_ = null;
+        } else {
+          sliceStatus_ = null;
+          sliceStatusBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_Slice_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.Slice getDefaultInstanceForType() {
+        return context.ContextOuterClass.Slice.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.Slice build() {
+        context.ContextOuterClass.Slice result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.Slice buildPartial() {
+        context.ContextOuterClass.Slice result = new context.ContextOuterClass.Slice(this);
+        int from_bitField0_ = bitField0_;
+        if (sliceIdBuilder_ == null) {
+          result.sliceId_ = sliceId_;
+        } else {
+          result.sliceId_ = sliceIdBuilder_.build();
+        }
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            sliceEndpointIds_ = java.util.Collections.unmodifiableList(sliceEndpointIds_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.sliceEndpointIds_ = sliceEndpointIds_;
+        } else {
+          result.sliceEndpointIds_ = sliceEndpointIdsBuilder_.build();
+        }
+        if (sliceConstraintsBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) != 0)) {
+            sliceConstraints_ = java.util.Collections.unmodifiableList(sliceConstraints_);
+            bitField0_ = (bitField0_ & ~0x00000002);
+          }
+          result.sliceConstraints_ = sliceConstraints_;
+        } else {
+          result.sliceConstraints_ = sliceConstraintsBuilder_.build();
+        }
+        if (sliceServiceIdsBuilder_ == null) {
+          if (((bitField0_ & 0x00000004) != 0)) {
+            sliceServiceIds_ = java.util.Collections.unmodifiableList(sliceServiceIds_);
+            bitField0_ = (bitField0_ & ~0x00000004);
+          }
+          result.sliceServiceIds_ = sliceServiceIds_;
+        } else {
+          result.sliceServiceIds_ = sliceServiceIdsBuilder_.build();
+        }
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (((bitField0_ & 0x00000008) != 0)) {
+            sliceSubsliceIds_ = java.util.Collections.unmodifiableList(sliceSubsliceIds_);
+            bitField0_ = (bitField0_ & ~0x00000008);
+          }
+          result.sliceSubsliceIds_ = sliceSubsliceIds_;
+        } else {
+          result.sliceSubsliceIds_ = sliceSubsliceIdsBuilder_.build();
+        }
+        if (sliceStatusBuilder_ == null) {
+          result.sliceStatus_ = sliceStatus_;
+        } else {
+          result.sliceStatus_ = sliceStatusBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.Slice) {
+          return mergeFrom((context.ContextOuterClass.Slice)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.Slice other) {
+        if (other == context.ContextOuterClass.Slice.getDefaultInstance()) return this;
+        if (other.hasSliceId()) {
+          mergeSliceId(other.getSliceId());
+        }
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (!other.sliceEndpointIds_.isEmpty()) {
+            if (sliceEndpointIds_.isEmpty()) {
+              sliceEndpointIds_ = other.sliceEndpointIds_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureSliceEndpointIdsIsMutable();
+              sliceEndpointIds_.addAll(other.sliceEndpointIds_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceEndpointIds_.isEmpty()) {
+            if (sliceEndpointIdsBuilder_.isEmpty()) {
+              sliceEndpointIdsBuilder_.dispose();
+              sliceEndpointIdsBuilder_ = null;
+              sliceEndpointIds_ = other.sliceEndpointIds_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              sliceEndpointIdsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceEndpointIdsFieldBuilder() : null;
+            } else {
+              sliceEndpointIdsBuilder_.addAllMessages(other.sliceEndpointIds_);
+            }
+          }
+        }
+        if (sliceConstraintsBuilder_ == null) {
+          if (!other.sliceConstraints_.isEmpty()) {
+            if (sliceConstraints_.isEmpty()) {
+              sliceConstraints_ = other.sliceConstraints_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+            } else {
+              ensureSliceConstraintsIsMutable();
+              sliceConstraints_.addAll(other.sliceConstraints_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceConstraints_.isEmpty()) {
+            if (sliceConstraintsBuilder_.isEmpty()) {
+              sliceConstraintsBuilder_.dispose();
+              sliceConstraintsBuilder_ = null;
+              sliceConstraints_ = other.sliceConstraints_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+              sliceConstraintsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceConstraintsFieldBuilder() : null;
+            } else {
+              sliceConstraintsBuilder_.addAllMessages(other.sliceConstraints_);
+            }
+          }
+        }
+        if (sliceServiceIdsBuilder_ == null) {
+          if (!other.sliceServiceIds_.isEmpty()) {
+            if (sliceServiceIds_.isEmpty()) {
+              sliceServiceIds_ = other.sliceServiceIds_;
+              bitField0_ = (bitField0_ & ~0x00000004);
+            } else {
+              ensureSliceServiceIdsIsMutable();
+              sliceServiceIds_.addAll(other.sliceServiceIds_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceServiceIds_.isEmpty()) {
+            if (sliceServiceIdsBuilder_.isEmpty()) {
+              sliceServiceIdsBuilder_.dispose();
+              sliceServiceIdsBuilder_ = null;
+              sliceServiceIds_ = other.sliceServiceIds_;
+              bitField0_ = (bitField0_ & ~0x00000004);
+              sliceServiceIdsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceServiceIdsFieldBuilder() : null;
+            } else {
+              sliceServiceIdsBuilder_.addAllMessages(other.sliceServiceIds_);
+            }
+          }
+        }
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (!other.sliceSubsliceIds_.isEmpty()) {
+            if (sliceSubsliceIds_.isEmpty()) {
+              sliceSubsliceIds_ = other.sliceSubsliceIds_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+            } else {
+              ensureSliceSubsliceIdsIsMutable();
+              sliceSubsliceIds_.addAll(other.sliceSubsliceIds_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceSubsliceIds_.isEmpty()) {
+            if (sliceSubsliceIdsBuilder_.isEmpty()) {
+              sliceSubsliceIdsBuilder_.dispose();
+              sliceSubsliceIdsBuilder_ = null;
+              sliceSubsliceIds_ = other.sliceSubsliceIds_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+              sliceSubsliceIdsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceSubsliceIdsFieldBuilder() : null;
+            } else {
+              sliceSubsliceIdsBuilder_.addAllMessages(other.sliceSubsliceIds_);
+            }
+          }
+        }
+        if (other.hasSliceStatus()) {
+          mergeSliceStatus(other.getSliceStatus());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.Slice parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.Slice) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private context.ContextOuterClass.SliceId sliceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceIdBuilder_;
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       * @return Whether the sliceId field is set.
+       */
+      public boolean hasSliceId() {
+        return sliceIdBuilder_ != null || sliceId_ != null;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       * @return The sliceId.
+       */
+      public context.ContextOuterClass.SliceId getSliceId() {
+        if (sliceIdBuilder_ == null) {
+          return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+        } else {
+          return sliceIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public Builder setSliceId(context.ContextOuterClass.SliceId value) {
+        if (sliceIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          sliceId_ = value;
+          onChanged();
+        } else {
+          sliceIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public Builder setSliceId(
+          context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = builderForValue.build();
+          onChanged();
+        } else {
+          sliceIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public Builder mergeSliceId(context.ContextOuterClass.SliceId value) {
+        if (sliceIdBuilder_ == null) {
+          if (sliceId_ != null) {
+            sliceId_ =
+              context.ContextOuterClass.SliceId.newBuilder(sliceId_).mergeFrom(value).buildPartial();
+          } else {
+            sliceId_ = value;
+          }
+          onChanged();
+        } else {
+          sliceIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public Builder clearSliceId() {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+          onChanged();
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
+        
+        onChanged();
+        return getSliceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
+        if (sliceIdBuilder_ != null) {
+          return sliceIdBuilder_.getMessageOrBuilder();
+        } else {
+          return sliceId_ == null ?
+              context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+        }
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> 
+          getSliceIdFieldBuilder() {
+        if (sliceIdBuilder_ == null) {
+          sliceIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder>(
+                  getSliceId(),
+                  getParentForChildren(),
+                  isClean());
+          sliceId_ = null;
+        }
+        return sliceIdBuilder_;
+      }
+
+      private java.util.List<context.ContextOuterClass.EndPointId> sliceEndpointIds_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceEndpointIdsIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          sliceEndpointIds_ = new java.util.ArrayList<context.ContextOuterClass.EndPointId>(sliceEndpointIds_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder> sliceEndpointIdsBuilder_;
+
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public java.util.List<context.ContextOuterClass.EndPointId> getSliceEndpointIdsList() {
+        if (sliceEndpointIdsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceEndpointIds_);
+        } else {
+          return sliceEndpointIdsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public int getSliceEndpointIdsCount() {
+        if (sliceEndpointIdsBuilder_ == null) {
+          return sliceEndpointIds_.size();
+        } else {
+          return sliceEndpointIdsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointId getSliceEndpointIds(int index) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          return sliceEndpointIds_.get(index);
+        } else {
+          return sliceEndpointIdsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder setSliceEndpointIds(
+          int index, context.ContextOuterClass.EndPointId value) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.set(index, value);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder setSliceEndpointIds(
+          int index, context.ContextOuterClass.EndPointId.Builder builderForValue) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addSliceEndpointIds(context.ContextOuterClass.EndPointId value) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.add(value);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addSliceEndpointIds(
+          int index, context.ContextOuterClass.EndPointId value) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.add(index, value);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addSliceEndpointIds(
+          context.ContextOuterClass.EndPointId.Builder builderForValue) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addSliceEndpointIds(
+          int index, context.ContextOuterClass.EndPointId.Builder builderForValue) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addAllSliceEndpointIds(
+          java.lang.Iterable<? extends context.ContextOuterClass.EndPointId> values) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceEndpointIds_);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder clearSliceEndpointIds() {
+        if (sliceEndpointIdsBuilder_ == null) {
+          sliceEndpointIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder removeSliceEndpointIds(int index) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.remove(index);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointId.Builder getSliceEndpointIdsBuilder(
+          int index) {
+        return getSliceEndpointIdsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointIdOrBuilder getSliceEndpointIdsOrBuilder(
+          int index) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          return sliceEndpointIds_.get(index);  } else {
+          return sliceEndpointIdsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.EndPointIdOrBuilder> 
+           getSliceEndpointIdsOrBuilderList() {
+        if (sliceEndpointIdsBuilder_ != null) {
+          return sliceEndpointIdsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceEndpointIds_);
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointId.Builder addSliceEndpointIdsBuilder() {
+        return getSliceEndpointIdsFieldBuilder().addBuilder(
+            context.ContextOuterClass.EndPointId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointId.Builder addSliceEndpointIdsBuilder(
+          int index) {
+        return getSliceEndpointIdsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.EndPointId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public java.util.List<context.ContextOuterClass.EndPointId.Builder> 
+           getSliceEndpointIdsBuilderList() {
+        return getSliceEndpointIdsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder> 
+          getSliceEndpointIdsFieldBuilder() {
+        if (sliceEndpointIdsBuilder_ == null) {
+          sliceEndpointIdsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder>(
+                  sliceEndpointIds_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceEndpointIds_ = null;
+        }
+        return sliceEndpointIdsBuilder_;
+      }
+
+      private java.util.List<context.ContextOuterClass.Constraint> sliceConstraints_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceConstraintsIsMutable() {
+        if (!((bitField0_ & 0x00000002) != 0)) {
+          sliceConstraints_ = new java.util.ArrayList<context.ContextOuterClass.Constraint>(sliceConstraints_);
+          bitField0_ |= 0x00000002;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.Constraint, context.ContextOuterClass.Constraint.Builder, context.ContextOuterClass.ConstraintOrBuilder> sliceConstraintsBuilder_;
+
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public java.util.List<context.ContextOuterClass.Constraint> getSliceConstraintsList() {
+        if (sliceConstraintsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceConstraints_);
+        } else {
+          return sliceConstraintsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public int getSliceConstraintsCount() {
+        if (sliceConstraintsBuilder_ == null) {
+          return sliceConstraints_.size();
+        } else {
+          return sliceConstraintsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.Constraint getSliceConstraints(int index) {
+        if (sliceConstraintsBuilder_ == null) {
+          return sliceConstraints_.get(index);
+        } else {
+          return sliceConstraintsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder setSliceConstraints(
+          int index, context.ContextOuterClass.Constraint value) {
+        if (sliceConstraintsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.set(index, value);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder setSliceConstraints(
+          int index, context.ContextOuterClass.Constraint.Builder builderForValue) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addSliceConstraints(context.ContextOuterClass.Constraint value) {
+        if (sliceConstraintsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.add(value);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addSliceConstraints(
+          int index, context.ContextOuterClass.Constraint value) {
+        if (sliceConstraintsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.add(index, value);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addSliceConstraints(
+          context.ContextOuterClass.Constraint.Builder builderForValue) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addSliceConstraints(
+          int index, context.ContextOuterClass.Constraint.Builder builderForValue) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addAllSliceConstraints(
+          java.lang.Iterable<? extends context.ContextOuterClass.Constraint> values) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceConstraints_);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder clearSliceConstraints() {
+        if (sliceConstraintsBuilder_ == null) {
+          sliceConstraints_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder removeSliceConstraints(int index) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.remove(index);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.Constraint.Builder getSliceConstraintsBuilder(
+          int index) {
+        return getSliceConstraintsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.ConstraintOrBuilder getSliceConstraintsOrBuilder(
+          int index) {
+        if (sliceConstraintsBuilder_ == null) {
+          return sliceConstraints_.get(index);  } else {
+          return sliceConstraintsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.ConstraintOrBuilder> 
+           getSliceConstraintsOrBuilderList() {
+        if (sliceConstraintsBuilder_ != null) {
+          return sliceConstraintsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceConstraints_);
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.Constraint.Builder addSliceConstraintsBuilder() {
+        return getSliceConstraintsFieldBuilder().addBuilder(
+            context.ContextOuterClass.Constraint.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.Constraint.Builder addSliceConstraintsBuilder(
+          int index) {
+        return getSliceConstraintsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.Constraint.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public java.util.List<context.ContextOuterClass.Constraint.Builder> 
+           getSliceConstraintsBuilderList() {
+        return getSliceConstraintsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.Constraint, context.ContextOuterClass.Constraint.Builder, context.ContextOuterClass.ConstraintOrBuilder> 
+          getSliceConstraintsFieldBuilder() {
+        if (sliceConstraintsBuilder_ == null) {
+          sliceConstraintsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.Constraint, context.ContextOuterClass.Constraint.Builder, context.ContextOuterClass.ConstraintOrBuilder>(
+                  sliceConstraints_,
+                  ((bitField0_ & 0x00000002) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceConstraints_ = null;
+        }
+        return sliceConstraintsBuilder_;
+      }
+
+      private java.util.List<context.ContextOuterClass.ServiceId> sliceServiceIds_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceServiceIdsIsMutable() {
+        if (!((bitField0_ & 0x00000004) != 0)) {
+          sliceServiceIds_ = new java.util.ArrayList<context.ContextOuterClass.ServiceId>(sliceServiceIds_);
+          bitField0_ |= 0x00000004;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> sliceServiceIdsBuilder_;
+
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public java.util.List<context.ContextOuterClass.ServiceId> getSliceServiceIdsList() {
+        if (sliceServiceIdsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceServiceIds_);
+        } else {
+          return sliceServiceIdsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public int getSliceServiceIdsCount() {
+        if (sliceServiceIdsBuilder_ == null) {
+          return sliceServiceIds_.size();
+        } else {
+          return sliceServiceIdsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceId getSliceServiceIds(int index) {
+        if (sliceServiceIdsBuilder_ == null) {
+          return sliceServiceIds_.get(index);
+        } else {
+          return sliceServiceIdsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder setSliceServiceIds(
+          int index, context.ContextOuterClass.ServiceId value) {
+        if (sliceServiceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.set(index, value);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder setSliceServiceIds(
+          int index, context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addSliceServiceIds(context.ContextOuterClass.ServiceId value) {
+        if (sliceServiceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.add(value);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addSliceServiceIds(
+          int index, context.ContextOuterClass.ServiceId value) {
+        if (sliceServiceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.add(index, value);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addSliceServiceIds(
+          context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addSliceServiceIds(
+          int index, context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addAllSliceServiceIds(
+          java.lang.Iterable<? extends context.ContextOuterClass.ServiceId> values) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceServiceIds_);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder clearSliceServiceIds() {
+        if (sliceServiceIdsBuilder_ == null) {
+          sliceServiceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000004);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder removeSliceServiceIds(int index) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.remove(index);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder getSliceServiceIdsBuilder(
+          int index) {
+        return getSliceServiceIdsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceIdOrBuilder getSliceServiceIdsOrBuilder(
+          int index) {
+        if (sliceServiceIdsBuilder_ == null) {
+          return sliceServiceIds_.get(index);  } else {
+          return sliceServiceIdsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.ServiceIdOrBuilder> 
+           getSliceServiceIdsOrBuilderList() {
+        if (sliceServiceIdsBuilder_ != null) {
+          return sliceServiceIdsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceServiceIds_);
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder addSliceServiceIdsBuilder() {
+        return getSliceServiceIdsFieldBuilder().addBuilder(
+            context.ContextOuterClass.ServiceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder addSliceServiceIdsBuilder(
+          int index) {
+        return getSliceServiceIdsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.ServiceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public java.util.List<context.ContextOuterClass.ServiceId.Builder> 
+           getSliceServiceIdsBuilderList() {
+        return getSliceServiceIdsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> 
+          getSliceServiceIdsFieldBuilder() {
+        if (sliceServiceIdsBuilder_ == null) {
+          sliceServiceIdsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder>(
+                  sliceServiceIds_,
+                  ((bitField0_ & 0x00000004) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceServiceIds_ = null;
+        }
+        return sliceServiceIdsBuilder_;
+      }
+
+      private java.util.List<context.ContextOuterClass.SliceId> sliceSubsliceIds_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceSubsliceIdsIsMutable() {
+        if (!((bitField0_ & 0x00000008) != 0)) {
+          sliceSubsliceIds_ = new java.util.ArrayList<context.ContextOuterClass.SliceId>(sliceSubsliceIds_);
+          bitField0_ |= 0x00000008;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceSubsliceIdsBuilder_;
+
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public java.util.List<context.ContextOuterClass.SliceId> getSliceSubsliceIdsList() {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceSubsliceIds_);
+        } else {
+          return sliceSubsliceIdsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public int getSliceSubsliceIdsCount() {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          return sliceSubsliceIds_.size();
+        } else {
+          return sliceSubsliceIdsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceId getSliceSubsliceIds(int index) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          return sliceSubsliceIds_.get(index);
+        } else {
+          return sliceSubsliceIdsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder setSliceSubsliceIds(
+          int index, context.ContextOuterClass.SliceId value) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.set(index, value);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder setSliceSubsliceIds(
+          int index, context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addSliceSubsliceIds(context.ContextOuterClass.SliceId value) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.add(value);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addSliceSubsliceIds(
+          int index, context.ContextOuterClass.SliceId value) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.add(index, value);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addSliceSubsliceIds(
+          context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addSliceSubsliceIds(
+          int index, context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addAllSliceSubsliceIds(
+          java.lang.Iterable<? extends context.ContextOuterClass.SliceId> values) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceSubsliceIds_);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder clearSliceSubsliceIds() {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          sliceSubsliceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder removeSliceSubsliceIds(int index) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.remove(index);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceSubsliceIdsBuilder(
+          int index) {
+        return getSliceSubsliceIdsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceIdOrBuilder getSliceSubsliceIdsOrBuilder(
+          int index) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          return sliceSubsliceIds_.get(index);  } else {
+          return sliceSubsliceIdsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+           getSliceSubsliceIdsOrBuilderList() {
+        if (sliceSubsliceIdsBuilder_ != null) {
+          return sliceSubsliceIdsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceSubsliceIds_);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder addSliceSubsliceIdsBuilder() {
+        return getSliceSubsliceIdsFieldBuilder().addBuilder(
+            context.ContextOuterClass.SliceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder addSliceSubsliceIdsBuilder(
+          int index) {
+        return getSliceSubsliceIdsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.SliceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public java.util.List<context.ContextOuterClass.SliceId.Builder> 
+           getSliceSubsliceIdsBuilderList() {
+        return getSliceSubsliceIdsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> 
+          getSliceSubsliceIdsFieldBuilder() {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          sliceSubsliceIdsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder>(
+                  sliceSubsliceIds_,
+                  ((bitField0_ & 0x00000008) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceSubsliceIds_ = null;
+        }
+        return sliceSubsliceIdsBuilder_;
+      }
+
+      private context.ContextOuterClass.SliceStatus sliceStatus_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceStatus, context.ContextOuterClass.SliceStatus.Builder, context.ContextOuterClass.SliceStatusOrBuilder> sliceStatusBuilder_;
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       * @return Whether the sliceStatus field is set.
+       */
+      public boolean hasSliceStatus() {
+        return sliceStatusBuilder_ != null || sliceStatus_ != null;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       * @return The sliceStatus.
+       */
+      public context.ContextOuterClass.SliceStatus getSliceStatus() {
+        if (sliceStatusBuilder_ == null) {
+          return sliceStatus_ == null ? context.ContextOuterClass.SliceStatus.getDefaultInstance() : sliceStatus_;
+        } else {
+          return sliceStatusBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public Builder setSliceStatus(context.ContextOuterClass.SliceStatus value) {
+        if (sliceStatusBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          sliceStatus_ = value;
+          onChanged();
+        } else {
+          sliceStatusBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public Builder setSliceStatus(
+          context.ContextOuterClass.SliceStatus.Builder builderForValue) {
+        if (sliceStatusBuilder_ == null) {
+          sliceStatus_ = builderForValue.build();
+          onChanged();
+        } else {
+          sliceStatusBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public Builder mergeSliceStatus(context.ContextOuterClass.SliceStatus value) {
+        if (sliceStatusBuilder_ == null) {
+          if (sliceStatus_ != null) {
+            sliceStatus_ =
+              context.ContextOuterClass.SliceStatus.newBuilder(sliceStatus_).mergeFrom(value).buildPartial();
+          } else {
+            sliceStatus_ = value;
+          }
+          onChanged();
+        } else {
+          sliceStatusBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public Builder clearSliceStatus() {
+        if (sliceStatusBuilder_ == null) {
+          sliceStatus_ = null;
+          onChanged();
+        } else {
+          sliceStatus_ = null;
+          sliceStatusBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public context.ContextOuterClass.SliceStatus.Builder getSliceStatusBuilder() {
+        
+        onChanged();
+        return getSliceStatusFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public context.ContextOuterClass.SliceStatusOrBuilder getSliceStatusOrBuilder() {
+        if (sliceStatusBuilder_ != null) {
+          return sliceStatusBuilder_.getMessageOrBuilder();
+        } else {
+          return sliceStatus_ == null ?
+              context.ContextOuterClass.SliceStatus.getDefaultInstance() : sliceStatus_;
+        }
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceStatus, context.ContextOuterClass.SliceStatus.Builder, context.ContextOuterClass.SliceStatusOrBuilder> 
+          getSliceStatusFieldBuilder() {
+        if (sliceStatusBuilder_ == null) {
+          sliceStatusBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.SliceStatus, context.ContextOuterClass.SliceStatus.Builder, context.ContextOuterClass.SliceStatusOrBuilder>(
+                  getSliceStatus(),
+                  getParentForChildren(),
+                  isClean());
+          sliceStatus_ = null;
+        }
+        return sliceStatusBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.Slice)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.Slice)
+    private static final context.ContextOuterClass.Slice DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.Slice();
+    }
+
+    public static context.ContextOuterClass.Slice getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Slice>
+        PARSER = new com.google.protobuf.AbstractParser<Slice>() {
+      @java.lang.Override
+      public Slice parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Slice(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Slice> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Slice> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.Slice getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceStatusOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceStatus)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.SliceStatusEnum slice_status = 1;</code>
+     * @return The enum numeric value on the wire for sliceStatus.
+     */
+    int getSliceStatusValue();
+    /**
+     * <code>.context.SliceStatusEnum slice_status = 1;</code>
+     * @return The sliceStatus.
+     */
+    context.ContextOuterClass.SliceStatusEnum getSliceStatus();
+  }
+  /**
+   * Protobuf type {@code context.SliceStatus}
+   */
+  public static final class SliceStatus extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.SliceStatus)
+      SliceStatusOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use SliceStatus.newBuilder() to construct.
+    private SliceStatus(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private SliceStatus() {
+      sliceStatus_ = 0;
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new SliceStatus();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SliceStatus(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 8: {
+              int rawValue = input.readEnum();
+
+              sliceStatus_ = rawValue;
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_SliceStatus_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_SliceStatus_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.SliceStatus.class, context.ContextOuterClass.SliceStatus.Builder.class);
+    }
+
+    public static final int SLICE_STATUS_FIELD_NUMBER = 1;
+    private int sliceStatus_;
+    /**
+     * <code>.context.SliceStatusEnum slice_status = 1;</code>
+     * @return The enum numeric value on the wire for sliceStatus.
+     */
+    @java.lang.Override public int getSliceStatusValue() {
+      return sliceStatus_;
+    }
+    /**
+     * <code>.context.SliceStatusEnum slice_status = 1;</code>
+     * @return The sliceStatus.
+     */
+    @java.lang.Override public context.ContextOuterClass.SliceStatusEnum getSliceStatus() {
+      @SuppressWarnings("deprecation")
+      context.ContextOuterClass.SliceStatusEnum result = context.ContextOuterClass.SliceStatusEnum.valueOf(sliceStatus_);
+      return result == null ? context.ContextOuterClass.SliceStatusEnum.UNRECOGNIZED : result;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (sliceStatus_ != context.ContextOuterClass.SliceStatusEnum.SLICESTATUS_UNDEFINED.getNumber()) {
+        output.writeEnum(1, sliceStatus_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (sliceStatus_ != context.ContextOuterClass.SliceStatusEnum.SLICESTATUS_UNDEFINED.getNumber()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(1, sliceStatus_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.SliceStatus)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.SliceStatus other = (context.ContextOuterClass.SliceStatus) obj;
+
+      if (sliceStatus_ != other.sliceStatus_) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + SLICE_STATUS_FIELD_NUMBER;
+      hash = (53 * hash) + sliceStatus_;
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceStatus parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.SliceStatus prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.SliceStatus}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.SliceStatus)
+        context.ContextOuterClass.SliceStatusOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_SliceStatus_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_SliceStatus_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.SliceStatus.class, context.ContextOuterClass.SliceStatus.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.SliceStatus.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        sliceStatus_ = 0;
+
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_SliceStatus_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceStatus getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceStatus.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceStatus build() {
+        context.ContextOuterClass.SliceStatus result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceStatus buildPartial() {
+        context.ContextOuterClass.SliceStatus result = new context.ContextOuterClass.SliceStatus(this);
+        result.sliceStatus_ = sliceStatus_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceStatus) {
+          return mergeFrom((context.ContextOuterClass.SliceStatus)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceStatus other) {
+        if (other == context.ContextOuterClass.SliceStatus.getDefaultInstance()) return this;
+        if (other.sliceStatus_ != 0) {
+          setSliceStatusValue(other.getSliceStatusValue());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceStatus parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceStatus) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private int sliceStatus_ = 0;
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @return The enum numeric value on the wire for sliceStatus.
+       */
+      @java.lang.Override public int getSliceStatusValue() {
+        return sliceStatus_;
+      }
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @param value The enum numeric value on the wire for sliceStatus to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSliceStatusValue(int value) {
+        
+        sliceStatus_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @return The sliceStatus.
+       */
+      @java.lang.Override
+      public context.ContextOuterClass.SliceStatusEnum getSliceStatus() {
+        @SuppressWarnings("deprecation")
+        context.ContextOuterClass.SliceStatusEnum result = context.ContextOuterClass.SliceStatusEnum.valueOf(sliceStatus_);
+        return result == null ? context.ContextOuterClass.SliceStatusEnum.UNRECOGNIZED : result;
+      }
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @param value The sliceStatus to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSliceStatus(context.ContextOuterClass.SliceStatusEnum value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        
+        sliceStatus_ = value.getNumber();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSliceStatus() {
+        
+        sliceStatus_ = 0;
+        onChanged();
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceStatus)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceStatus)
+    private static final context.ContextOuterClass.SliceStatus DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceStatus();
+    }
+
+    public static context.ContextOuterClass.SliceStatus getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceStatus>
+        PARSER = new com.google.protobuf.AbstractParser<SliceStatus>() {
+      @java.lang.Override
+      public SliceStatus parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceStatus(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceStatus> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceStatus> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceStatus getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceIdListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceIdList)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    java.util.List<context.ContextOuterClass.SliceId> 
+        getSliceIdsList();
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    context.ContextOuterClass.SliceId getSliceIds(int index);
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    int getSliceIdsCount();
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+        getSliceIdsOrBuilderList();
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    context.ContextOuterClass.SliceIdOrBuilder getSliceIdsOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code context.SliceIdList}
+   */
+  public static final class SliceIdList extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.SliceIdList)
+      SliceIdListOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use SliceIdList.newBuilder() to construct.
+    private SliceIdList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private SliceIdList() {
+      sliceIds_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new SliceIdList();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SliceIdList(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                sliceIds_ = new java.util.ArrayList<context.ContextOuterClass.SliceId>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              sliceIds_.add(
+                  input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry));
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          sliceIds_ = java.util.Collections.unmodifiableList(sliceIds_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_SliceIdList_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_SliceIdList_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.SliceIdList.class, context.ContextOuterClass.SliceIdList.Builder.class);
+    }
+
+    public static final int SLICE_IDS_FIELD_NUMBER = 1;
+    private java.util.List<context.ContextOuterClass.SliceId> sliceIds_;
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.SliceId> getSliceIdsList() {
+      return sliceIds_;
+    }
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+        getSliceIdsOrBuilderList() {
+      return sliceIds_;
+    }
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public int getSliceIdsCount() {
+      return sliceIds_.size();
+    }
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getSliceIds(int index) {
+      return sliceIds_.get(index);
+    }
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdOrBuilder getSliceIdsOrBuilder(
+        int index) {
+      return sliceIds_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < sliceIds_.size(); i++) {
+        output.writeMessage(1, sliceIds_.get(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < sliceIds_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, sliceIds_.get(i));
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.SliceIdList)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.SliceIdList other = (context.ContextOuterClass.SliceIdList) obj;
+
+      if (!getSliceIdsList()
+          .equals(other.getSliceIdsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getSliceIdsCount() > 0) {
+        hash = (37 * hash) + SLICE_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceIdsList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceIdList parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.SliceIdList prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.SliceIdList}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.SliceIdList)
+        context.ContextOuterClass.SliceIdListOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_SliceIdList_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_SliceIdList_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.SliceIdList.class, context.ContextOuterClass.SliceIdList.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.SliceIdList.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getSliceIdsFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (sliceIdsBuilder_ == null) {
+          sliceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          sliceIdsBuilder_.clear();
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_SliceIdList_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceIdList getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceIdList.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceIdList build() {
+        context.ContextOuterClass.SliceIdList result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceIdList buildPartial() {
+        context.ContextOuterClass.SliceIdList result = new context.ContextOuterClass.SliceIdList(this);
+        int from_bitField0_ = bitField0_;
+        if (sliceIdsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            sliceIds_ = java.util.Collections.unmodifiableList(sliceIds_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.sliceIds_ = sliceIds_;
+        } else {
+          result.sliceIds_ = sliceIdsBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceIdList) {
+          return mergeFrom((context.ContextOuterClass.SliceIdList)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceIdList other) {
+        if (other == context.ContextOuterClass.SliceIdList.getDefaultInstance()) return this;
+        if (sliceIdsBuilder_ == null) {
+          if (!other.sliceIds_.isEmpty()) {
+            if (sliceIds_.isEmpty()) {
+              sliceIds_ = other.sliceIds_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureSliceIdsIsMutable();
+              sliceIds_.addAll(other.sliceIds_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceIds_.isEmpty()) {
+            if (sliceIdsBuilder_.isEmpty()) {
+              sliceIdsBuilder_.dispose();
+              sliceIdsBuilder_ = null;
+              sliceIds_ = other.sliceIds_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              sliceIdsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceIdsFieldBuilder() : null;
+            } else {
+              sliceIdsBuilder_.addAllMessages(other.sliceIds_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceIdList parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceIdList) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.util.List<context.ContextOuterClass.SliceId> sliceIds_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceIdsIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          sliceIds_ = new java.util.ArrayList<context.ContextOuterClass.SliceId>(sliceIds_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceIdsBuilder_;
+
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public java.util.List<context.ContextOuterClass.SliceId> getSliceIdsList() {
+        if (sliceIdsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceIds_);
+        } else {
+          return sliceIdsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public int getSliceIdsCount() {
+        if (sliceIdsBuilder_ == null) {
+          return sliceIds_.size();
+        } else {
+          return sliceIdsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId getSliceIds(int index) {
+        if (sliceIdsBuilder_ == null) {
+          return sliceIds_.get(index);
+        } else {
+          return sliceIdsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder setSliceIds(
+          int index, context.ContextOuterClass.SliceId value) {
+        if (sliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceIdsIsMutable();
+          sliceIds_.set(index, value);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder setSliceIds(
+          int index, context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          sliceIds_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceIdsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addSliceIds(context.ContextOuterClass.SliceId value) {
+        if (sliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceIdsIsMutable();
+          sliceIds_.add(value);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addSliceIds(
+          int index, context.ContextOuterClass.SliceId value) {
+        if (sliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceIdsIsMutable();
+          sliceIds_.add(index, value);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addSliceIds(
+          context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          sliceIds_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addSliceIds(
+          int index, context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          sliceIds_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addAllSliceIds(
+          java.lang.Iterable<? extends context.ContextOuterClass.SliceId> values) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceIds_);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder clearSliceIds() {
+        if (sliceIdsBuilder_ == null) {
+          sliceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder removeSliceIds(int index) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          sliceIds_.remove(index);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceIdsBuilder(
+          int index) {
+        return getSliceIdsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceIdOrBuilder getSliceIdsOrBuilder(
+          int index) {
+        if (sliceIdsBuilder_ == null) {
+          return sliceIds_.get(index);  } else {
+          return sliceIdsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+           getSliceIdsOrBuilderList() {
+        if (sliceIdsBuilder_ != null) {
+          return sliceIdsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceIds_);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder addSliceIdsBuilder() {
+        return getSliceIdsFieldBuilder().addBuilder(
+            context.ContextOuterClass.SliceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder addSliceIdsBuilder(
+          int index) {
+        return getSliceIdsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.SliceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public java.util.List<context.ContextOuterClass.SliceId.Builder> 
+           getSliceIdsBuilderList() {
+        return getSliceIdsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> 
+          getSliceIdsFieldBuilder() {
+        if (sliceIdsBuilder_ == null) {
+          sliceIdsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder>(
+                  sliceIds_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceIds_ = null;
+        }
+        return sliceIdsBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceIdList)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceIdList)
+    private static final context.ContextOuterClass.SliceIdList DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceIdList();
+    }
+
+    public static context.ContextOuterClass.SliceIdList getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceIdList>
+        PARSER = new com.google.protobuf.AbstractParser<SliceIdList>() {
+      @java.lang.Override
+      public SliceIdList parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceIdList(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceIdList> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceIdList> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdList getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceList)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    java.util.List<context.ContextOuterClass.Slice> 
+        getSlicesList();
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    context.ContextOuterClass.Slice getSlices(int index);
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    int getSlicesCount();
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.SliceOrBuilder> 
+        getSlicesOrBuilderList();
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    context.ContextOuterClass.SliceOrBuilder getSlicesOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code context.SliceList}
+   */
+  public static final class SliceList extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.SliceList)
+      SliceListOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use SliceList.newBuilder() to construct.
+    private SliceList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private SliceList() {
+      slices_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new SliceList();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SliceList(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                slices_ = new java.util.ArrayList<context.ContextOuterClass.Slice>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              slices_.add(
+                  input.readMessage(context.ContextOuterClass.Slice.parser(), extensionRegistry));
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          slices_ = java.util.Collections.unmodifiableList(slices_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_SliceList_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_SliceList_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.SliceList.class, context.ContextOuterClass.SliceList.Builder.class);
+    }
+
+    public static final int SLICES_FIELD_NUMBER = 1;
+    private java.util.List<context.ContextOuterClass.Slice> slices_;
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.Slice> getSlicesList() {
+      return slices_;
+    }
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.SliceOrBuilder> 
+        getSlicesOrBuilderList() {
+      return slices_;
+    }
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public int getSlicesCount() {
+      return slices_.size();
+    }
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Slice getSlices(int index) {
+      return slices_.get(index);
+    }
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceOrBuilder getSlicesOrBuilder(
+        int index) {
+      return slices_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < slices_.size(); i++) {
+        output.writeMessage(1, slices_.get(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < slices_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, slices_.get(i));
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.SliceList)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.SliceList other = (context.ContextOuterClass.SliceList) obj;
+
+      if (!getSlicesList()
+          .equals(other.getSlicesList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getSlicesCount() > 0) {
+        hash = (37 * hash) + SLICES_FIELD_NUMBER;
+        hash = (53 * hash) + getSlicesList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.SliceList parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceList parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.SliceList prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.SliceList}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.SliceList)
+        context.ContextOuterClass.SliceListOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_SliceList_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_SliceList_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.SliceList.class, context.ContextOuterClass.SliceList.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.SliceList.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getSlicesFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (slicesBuilder_ == null) {
+          slices_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          slicesBuilder_.clear();
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_SliceList_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceList getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceList.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceList build() {
+        context.ContextOuterClass.SliceList result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceList buildPartial() {
+        context.ContextOuterClass.SliceList result = new context.ContextOuterClass.SliceList(this);
+        int from_bitField0_ = bitField0_;
+        if (slicesBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            slices_ = java.util.Collections.unmodifiableList(slices_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.slices_ = slices_;
+        } else {
+          result.slices_ = slicesBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceList) {
+          return mergeFrom((context.ContextOuterClass.SliceList)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceList other) {
+        if (other == context.ContextOuterClass.SliceList.getDefaultInstance()) return this;
+        if (slicesBuilder_ == null) {
+          if (!other.slices_.isEmpty()) {
+            if (slices_.isEmpty()) {
+              slices_ = other.slices_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureSlicesIsMutable();
+              slices_.addAll(other.slices_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.slices_.isEmpty()) {
+            if (slicesBuilder_.isEmpty()) {
+              slicesBuilder_.dispose();
+              slicesBuilder_ = null;
+              slices_ = other.slices_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              slicesBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSlicesFieldBuilder() : null;
+            } else {
+              slicesBuilder_.addAllMessages(other.slices_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceList parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceList) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.util.List<context.ContextOuterClass.Slice> slices_ =
+        java.util.Collections.emptyList();
+      private void ensureSlicesIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          slices_ = new java.util.ArrayList<context.ContextOuterClass.Slice>(slices_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.Slice, context.ContextOuterClass.Slice.Builder, context.ContextOuterClass.SliceOrBuilder> slicesBuilder_;
+
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public java.util.List<context.ContextOuterClass.Slice> getSlicesList() {
+        if (slicesBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(slices_);
+        } else {
+          return slicesBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public int getSlicesCount() {
+        if (slicesBuilder_ == null) {
+          return slices_.size();
+        } else {
+          return slicesBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.Slice getSlices(int index) {
+        if (slicesBuilder_ == null) {
+          return slices_.get(index);
+        } else {
+          return slicesBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder setSlices(
+          int index, context.ContextOuterClass.Slice value) {
+        if (slicesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSlicesIsMutable();
+          slices_.set(index, value);
+          onChanged();
+        } else {
+          slicesBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder setSlices(
+          int index, context.ContextOuterClass.Slice.Builder builderForValue) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          slices_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          slicesBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addSlices(context.ContextOuterClass.Slice value) {
+        if (slicesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSlicesIsMutable();
+          slices_.add(value);
+          onChanged();
+        } else {
+          slicesBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addSlices(
+          int index, context.ContextOuterClass.Slice value) {
+        if (slicesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSlicesIsMutable();
+          slices_.add(index, value);
+          onChanged();
+        } else {
+          slicesBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addSlices(
+          context.ContextOuterClass.Slice.Builder builderForValue) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          slices_.add(builderForValue.build());
+          onChanged();
+        } else {
+          slicesBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addSlices(
+          int index, context.ContextOuterClass.Slice.Builder builderForValue) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          slices_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          slicesBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addAllSlices(
+          java.lang.Iterable<? extends context.ContextOuterClass.Slice> values) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, slices_);
+          onChanged();
+        } else {
+          slicesBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder clearSlices() {
+        if (slicesBuilder_ == null) {
+          slices_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          slicesBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder removeSlices(int index) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          slices_.remove(index);
+          onChanged();
+        } else {
+          slicesBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.Slice.Builder getSlicesBuilder(
+          int index) {
+        return getSlicesFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.SliceOrBuilder getSlicesOrBuilder(
+          int index) {
+        if (slicesBuilder_ == null) {
+          return slices_.get(index);  } else {
+          return slicesBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.SliceOrBuilder> 
+           getSlicesOrBuilderList() {
+        if (slicesBuilder_ != null) {
+          return slicesBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(slices_);
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.Slice.Builder addSlicesBuilder() {
+        return getSlicesFieldBuilder().addBuilder(
+            context.ContextOuterClass.Slice.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.Slice.Builder addSlicesBuilder(
+          int index) {
+        return getSlicesFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.Slice.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public java.util.List<context.ContextOuterClass.Slice.Builder> 
+           getSlicesBuilderList() {
+        return getSlicesFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.Slice, context.ContextOuterClass.Slice.Builder, context.ContextOuterClass.SliceOrBuilder> 
+          getSlicesFieldBuilder() {
+        if (slicesBuilder_ == null) {
+          slicesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.Slice, context.ContextOuterClass.Slice.Builder, context.ContextOuterClass.SliceOrBuilder>(
+                  slices_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          slices_ = null;
+        }
+        return slicesBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceList)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceList)
+    private static final context.ContextOuterClass.SliceList DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceList();
+    }
+
+    public static context.ContextOuterClass.SliceList getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceList>
+        PARSER = new com.google.protobuf.AbstractParser<SliceList>() {
+      @java.lang.Override
+      public SliceList parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceList(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceList> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceList> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceList getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceEventOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceEvent)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.Event event = 1;</code>
+     * @return Whether the event field is set.
+     */
+    boolean hasEvent();
+    /**
+     * <code>.context.Event event = 1;</code>
+     * @return The event.
+     */
+    context.ContextOuterClass.Event getEvent();
+    /**
+     * <code>.context.Event event = 1;</code>
+     */
+    context.ContextOuterClass.EventOrBuilder getEventOrBuilder();
+
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     * @return Whether the sliceId field is set.
+     */
+    boolean hasSliceId();
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     * @return The sliceId.
+     */
+    context.ContextOuterClass.SliceId getSliceId();
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     */
+    context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
+  }
+  /**
+   * Protobuf type {@code context.SliceEvent}
+   */
+  public static final class SliceEvent extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.SliceEvent)
+      SliceEventOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use SliceEvent.newBuilder() to construct.
+    private SliceEvent(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private SliceEvent() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new SliceEvent();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SliceEvent(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              context.ContextOuterClass.Event.Builder subBuilder = null;
+              if (event_ != null) {
+                subBuilder = event_.toBuilder();
+              }
+              event_ = input.readMessage(context.ContextOuterClass.Event.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(event_);
+                event_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              context.ContextOuterClass.SliceId.Builder subBuilder = null;
+              if (sliceId_ != null) {
+                subBuilder = sliceId_.toBuilder();
+              }
+              sliceId_ = input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(sliceId_);
+                sliceId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_SliceEvent_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_SliceEvent_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.SliceEvent.class, context.ContextOuterClass.SliceEvent.Builder.class);
+    }
+
+    public static final int EVENT_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Event event_;
+    /**
+     * <code>.context.Event event = 1;</code>
+     * @return Whether the event field is set.
+     */
+    @java.lang.Override
+    public boolean hasEvent() {
+      return event_ != null;
+    }
+    /**
+     * <code>.context.Event event = 1;</code>
+     * @return The event.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Event getEvent() {
+      return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
+    }
+    /**
+     * <code>.context.Event event = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
+      return getEvent();
+    }
+
+    public static final int SLICE_ID_FIELD_NUMBER = 2;
+    private context.ContextOuterClass.SliceId sliceId_;
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     * @return Whether the sliceId field is set.
+     */
+    @java.lang.Override
+    public boolean hasSliceId() {
+      return sliceId_ != null;
+    }
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     * @return The sliceId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getSliceId() {
+      return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+    }
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
+      return getSliceId();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (event_ != null) {
+        output.writeMessage(1, getEvent());
+      }
+      if (sliceId_ != null) {
+        output.writeMessage(2, getSliceId());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (event_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getEvent());
+      }
+      if (sliceId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getSliceId());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.SliceEvent)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.SliceEvent other = (context.ContextOuterClass.SliceEvent) obj;
+
+      if (hasEvent() != other.hasEvent()) return false;
+      if (hasEvent()) {
+        if (!getEvent()
+            .equals(other.getEvent())) return false;
+      }
+      if (hasSliceId() != other.hasSliceId()) return false;
+      if (hasSliceId()) {
+        if (!getSliceId()
+            .equals(other.getSliceId())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasEvent()) {
+        hash = (37 * hash) + EVENT_FIELD_NUMBER;
+        hash = (53 * hash) + getEvent().hashCode();
+      }
+      if (hasSliceId()) {
+        hash = (37 * hash) + SLICE_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceId().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceEvent parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.SliceEvent prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.SliceEvent}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.SliceEvent)
+        context.ContextOuterClass.SliceEventOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_SliceEvent_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_SliceEvent_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.SliceEvent.class, context.ContextOuterClass.SliceEvent.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.SliceEvent.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (eventBuilder_ == null) {
+          event_ = null;
+        } else {
+          event_ = null;
+          eventBuilder_ = null;
+        }
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_SliceEvent_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceEvent getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceEvent.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceEvent build() {
+        context.ContextOuterClass.SliceEvent result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceEvent buildPartial() {
+        context.ContextOuterClass.SliceEvent result = new context.ContextOuterClass.SliceEvent(this);
+        if (eventBuilder_ == null) {
+          result.event_ = event_;
+        } else {
+          result.event_ = eventBuilder_.build();
+        }
+        if (sliceIdBuilder_ == null) {
+          result.sliceId_ = sliceId_;
+        } else {
+          result.sliceId_ = sliceIdBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceEvent) {
+          return mergeFrom((context.ContextOuterClass.SliceEvent)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceEvent other) {
+        if (other == context.ContextOuterClass.SliceEvent.getDefaultInstance()) return this;
+        if (other.hasEvent()) {
+          mergeEvent(other.getEvent());
+        }
+        if (other.hasSliceId()) {
+          mergeSliceId(other.getSliceId());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceEvent parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceEvent) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private context.ContextOuterClass.Event event_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> eventBuilder_;
+      /**
+       * <code>.context.Event event = 1;</code>
+       * @return Whether the event field is set.
+       */
+      public boolean hasEvent() {
+        return eventBuilder_ != null || event_ != null;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       * @return The event.
+       */
+      public context.ContextOuterClass.Event getEvent() {
+        if (eventBuilder_ == null) {
+          return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
+        } else {
+          return eventBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public Builder setEvent(context.ContextOuterClass.Event value) {
+        if (eventBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          event_ = value;
+          onChanged();
+        } else {
+          eventBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public Builder setEvent(
+          context.ContextOuterClass.Event.Builder builderForValue) {
+        if (eventBuilder_ == null) {
+          event_ = builderForValue.build();
+          onChanged();
+        } else {
+          eventBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public Builder mergeEvent(context.ContextOuterClass.Event value) {
+        if (eventBuilder_ == null) {
+          if (event_ != null) {
+            event_ =
+              context.ContextOuterClass.Event.newBuilder(event_).mergeFrom(value).buildPartial();
+          } else {
+            event_ = value;
+          }
+          onChanged();
+        } else {
+          eventBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public Builder clearEvent() {
+        if (eventBuilder_ == null) {
+          event_ = null;
+          onChanged();
+        } else {
+          event_ = null;
+          eventBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public context.ContextOuterClass.Event.Builder getEventBuilder() {
+        
+        onChanged();
+        return getEventFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
+        if (eventBuilder_ != null) {
+          return eventBuilder_.getMessageOrBuilder();
+        } else {
+          return event_ == null ?
+              context.ContextOuterClass.Event.getDefaultInstance() : event_;
+        }
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> 
+          getEventFieldBuilder() {
+        if (eventBuilder_ == null) {
+          eventBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder>(
+                  getEvent(),
+                  getParentForChildren(),
+                  isClean());
+          event_ = null;
+        }
+        return eventBuilder_;
+      }
+
+      private context.ContextOuterClass.SliceId sliceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceIdBuilder_;
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       * @return Whether the sliceId field is set.
+       */
+      public boolean hasSliceId() {
+        return sliceIdBuilder_ != null || sliceId_ != null;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       * @return The sliceId.
+       */
+      public context.ContextOuterClass.SliceId getSliceId() {
+        if (sliceIdBuilder_ == null) {
+          return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+        } else {
+          return sliceIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public Builder setSliceId(context.ContextOuterClass.SliceId value) {
+        if (sliceIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          sliceId_ = value;
+          onChanged();
+        } else {
+          sliceIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public Builder setSliceId(
+          context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = builderForValue.build();
+          onChanged();
+        } else {
+          sliceIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public Builder mergeSliceId(context.ContextOuterClass.SliceId value) {
+        if (sliceIdBuilder_ == null) {
+          if (sliceId_ != null) {
+            sliceId_ =
+              context.ContextOuterClass.SliceId.newBuilder(sliceId_).mergeFrom(value).buildPartial();
+          } else {
+            sliceId_ = value;
+          }
+          onChanged();
+        } else {
+          sliceIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public Builder clearSliceId() {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+          onChanged();
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
+        
+        onChanged();
+        return getSliceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
+        if (sliceIdBuilder_ != null) {
+          return sliceIdBuilder_.getMessageOrBuilder();
+        } else {
+          return sliceId_ == null ?
+              context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+        }
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> 
+          getSliceIdFieldBuilder() {
+        if (sliceIdBuilder_ == null) {
+          sliceIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder>(
+                  getSliceId(),
+                  getParentForChildren(),
+                  isClean());
+          sliceId_ = null;
+        }
+        return sliceIdBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceEvent)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceEvent)
+    private static final context.ContextOuterClass.SliceEvent DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceEvent();
+    }
+
+    public static context.ContextOuterClass.SliceEvent getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceEvent>
+        PARSER = new com.google.protobuf.AbstractParser<SliceEvent>() {
+      @java.lang.Override
+      public SliceEvent parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceEvent(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceEvent> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceEvent> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceEvent getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface ConnectionIdOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.ConnectionId)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     * @return Whether the connectionUuid field is set.
+     */
+    boolean hasConnectionUuid();
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     * @return The connectionUuid.
+     */
+    context.ContextOuterClass.Uuid getConnectionUuid();
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     */
+    context.ContextOuterClass.UuidOrBuilder getConnectionUuidOrBuilder();
+  }
+  /**
+   * <pre>
+   * ----- Connection ----------------------------------------------------------------------------------------------------
+   * </pre>
+   *
+   * Protobuf type {@code context.ConnectionId}
+   */
+  public static final class ConnectionId extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.ConnectionId)
+      ConnectionIdOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use ConnectionId.newBuilder() to construct.
+    private ConnectionId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private ConnectionId() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new ConnectionId();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private ConnectionId(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              context.ContextOuterClass.Uuid.Builder subBuilder = null;
+              if (connectionUuid_ != null) {
+                subBuilder = connectionUuid_.toBuilder();
+              }
+              connectionUuid_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(connectionUuid_);
+                connectionUuid_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_ConnectionId_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.ConnectionId.class, context.ContextOuterClass.ConnectionId.Builder.class);
+    }
+
+    public static final int CONNECTION_UUID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Uuid connectionUuid_;
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     * @return Whether the connectionUuid field is set.
+     */
+    @java.lang.Override
+    public boolean hasConnectionUuid() {
+      return connectionUuid_ != null;
+    }
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     * @return The connectionUuid.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Uuid getConnectionUuid() {
+      return connectionUuid_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : connectionUuid_;
+    }
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.UuidOrBuilder getConnectionUuidOrBuilder() {
+      return getConnectionUuid();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (connectionUuid_ != null) {
+        output.writeMessage(1, getConnectionUuid());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (connectionUuid_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getConnectionUuid());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.ConnectionId)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.ConnectionId other = (context.ContextOuterClass.ConnectionId) obj;
+
+      if (hasConnectionUuid() != other.hasConnectionUuid()) return false;
+      if (hasConnectionUuid()) {
+        if (!getConnectionUuid()
+            .equals(other.getConnectionUuid())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasConnectionUuid()) {
+        hash = (37 * hash) + CONNECTION_UUID_FIELD_NUMBER;
+        hash = (53 * hash) + getConnectionUuid().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.ConnectionId parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.ConnectionId prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * ----- Connection ----------------------------------------------------------------------------------------------------
+     * </pre>
+     *
+     * Protobuf type {@code context.ConnectionId}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.ConnectionId)
+        context.ContextOuterClass.ConnectionIdOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_ConnectionId_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.ConnectionId.class, context.ContextOuterClass.ConnectionId.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.ConnectionId.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (connectionUuidBuilder_ == null) {
+          connectionUuid_ = null;
+        } else {
+          connectionUuid_ = null;
+          connectionUuidBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.ConnectionId getDefaultInstanceForType() {
+        return context.ContextOuterClass.ConnectionId.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.ConnectionId build() {
+        context.ContextOuterClass.ConnectionId result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.ConnectionId buildPartial() {
+        context.ContextOuterClass.ConnectionId result = new context.ContextOuterClass.ConnectionId(this);
+        if (connectionUuidBuilder_ == null) {
+          result.connectionUuid_ = connectionUuid_;
+        } else {
+          result.connectionUuid_ = connectionUuidBuilder_.build();
         }
         onBuilt();
         return result;
@@ -37615,6 +43832,36 @@ public final class ContextOuterClass {
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_context_ServiceEvent_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceId_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceId_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_Slice_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_Slice_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceStatus_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceStatus_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceIdList_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceIdList_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceList_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceList_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceEvent_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceEvent_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_context_ConnectionId_descriptor;
   private static final 
@@ -37744,107 +43991,134 @@ public final class ContextOuterClass {
       "\"\n\010services\030\001 \003(\0132\020.context.Service\"U\n\014S" +
       "erviceEvent\022\035\n\005event\030\001 \001(\0132\016.context.Eve" +
       "nt\022&\n\nservice_id\030\002 \001(\0132\022.context.Service" +
-      "Id\"6\n\014ConnectionId\022&\n\017connection_uuid\030\001 " +
-      "\001(\0132\r.context.Uuid\"\304\001\n\nConnection\022,\n\rcon" +
-      "nection_id\030\001 \001(\0132\025.context.ConnectionId\022" +
-      "&\n\nservice_id\030\002 \001(\0132\022.context.ServiceId\022" +
-      "3\n\026path_hops_endpoint_ids\030\003 \003(\0132\023.contex" +
-      "t.EndPointId\022+\n\017sub_service_ids\030\004 \003(\0132\022." +
-      "context.ServiceId\"A\n\020ConnectionIdList\022-\n" +
-      "\016connection_ids\030\001 \003(\0132\025.context.Connecti" +
-      "onId\":\n\016ConnectionList\022(\n\013connections\030\001 " +
-      "\003(\0132\023.context.Connection\"^\n\017ConnectionEv" +
-      "ent\022\035\n\005event\030\001 \001(\0132\016.context.Event\022,\n\rco" +
-      "nnection_id\030\002 \001(\0132\025.context.ConnectionId" +
-      "\"\202\001\n\nEndPointId\022(\n\013topology_id\030\001 \001(\0132\023.c" +
-      "ontext.TopologyId\022$\n\tdevice_id\030\002 \001(\0132\021.c" +
-      "ontext.DeviceId\022$\n\rendpoint_uuid\030\003 \001(\0132\r" +
-      ".context.Uuid\"\206\001\n\010EndPoint\022(\n\013endpoint_i" +
-      "d\030\001 \001(\0132\023.context.EndPointId\022\025\n\rendpoint" +
-      "_type\030\002 \001(\t\0229\n\020kpi_sample_types\030\003 \003(\0162\037." +
-      "kpi_sample_types.KpiSampleType\"e\n\nConfig" +
-      "Rule\022)\n\006action\030\001 \001(\0162\031.context.ConfigAct" +
-      "ionEnum\022\024\n\014resource_key\030\002 \001(\t\022\026\n\016resourc" +
-      "e_value\030\003 \001(\t\"?\n\nConstraint\022\027\n\017constrain" +
-      "t_type\030\001 \001(\t\022\030\n\020constraint_value\030\002 \001(\t\"^" +
-      "\n\022TeraFlowController\022&\n\ncontext_id\030\001 \001(\013" +
-      "2\022.context.ContextId\022\022\n\nip_address\030\002 \001(\t" +
-      "\022\014\n\004port\030\003 \001(\r\"U\n\024AuthenticationResult\022&" +
-      "\n\ncontext_id\030\001 \001(\0132\022.context.ContextId\022\025" +
-      "\n\rauthenticated\030\002 \001(\010*j\n\rEventTypeEnum\022\027" +
-      "\n\023EVENTTYPE_UNDEFINED\020\000\022\024\n\020EVENTTYPE_CRE" +
-      "ATE\020\001\022\024\n\020EVENTTYPE_UPDATE\020\002\022\024\n\020EVENTTYPE" +
-      "_REMOVE\020\003*\305\001\n\020DeviceDriverEnum\022\032\n\026DEVICE" +
-      "DRIVER_UNDEFINED\020\000\022\033\n\027DEVICEDRIVER_OPENC" +
-      "ONFIG\020\001\022\036\n\032DEVICEDRIVER_TRANSPORT_API\020\002\022" +
-      "\023\n\017DEVICEDRIVER_P4\020\003\022&\n\"DEVICEDRIVER_IET" +
-      "F_NETWORK_TOPOLOGY\020\004\022\033\n\027DEVICEDRIVER_ONF" +
-      "_TR_352\020\005*\217\001\n\033DeviceOperationalStatusEnu" +
-      "m\022%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\020\000" +
-      "\022$\n DEVICEOPERATIONALSTATUS_DISABLED\020\001\022#" +
-      "\n\037DEVICEOPERATIONALSTATUS_ENABLED\020\002*\201\001\n\017" +
-      "ServiceTypeEnum\022\027\n\023SERVICETYPE_UNKNOWN\020\000" +
-      "\022\024\n\020SERVICETYPE_L3NM\020\001\022\024\n\020SERVICETYPE_L2" +
-      "NM\020\002\022)\n%SERVICETYPE_TAPI_CONNECTIVITY_SE" +
-      "RVICE\020\003*\210\001\n\021ServiceStatusEnum\022\033\n\027SERVICE" +
-      "STATUS_UNDEFINED\020\000\022\031\n\025SERVICESTATUS_PLAN" +
-      "NED\020\001\022\030\n\024SERVICESTATUS_ACTIVE\020\002\022!\n\035SERVI" +
-      "CESTATUS_PENDING_REMOVAL\020\003*]\n\020ConfigActi" +
-      "onEnum\022\032\n\026CONFIGACTION_UNDEFINED\020\000\022\024\n\020CO" +
-      "NFIGACTION_SET\020\001\022\027\n\023CONFIGACTION_DELETE\020" +
-      "\0022\255\020\n\016ContextService\022:\n\016ListContextIds\022\016" +
-      ".context.Empty\032\026.context.ContextIdList\"\000" +
-      "\0226\n\014ListContexts\022\016.context.Empty\032\024.conte" +
-      "xt.ContextList\"\000\0224\n\nGetContext\022\022.context" +
-      ".ContextId\032\020.context.Context\"\000\0224\n\nSetCon" +
-      "text\022\020.context.Context\032\022.context.Context" +
-      "Id\"\000\0225\n\rRemoveContext\022\022.context.ContextI" +
-      "d\032\016.context.Empty\"\000\022=\n\020GetContextEvents\022" +
-      "\016.context.Empty\032\025.context.ContextEvent\"\000" +
-      "0\001\022@\n\017ListTopologyIds\022\022.context.ContextI" +
-      "d\032\027.context.TopologyIdList\"\000\022=\n\016ListTopo" +
-      "logies\022\022.context.ContextId\032\025.context.Top" +
-      "ologyList\"\000\0227\n\013GetTopology\022\023.context.Top" +
-      "ologyId\032\021.context.Topology\"\000\0227\n\013SetTopol" +
-      "ogy\022\021.context.Topology\032\023.context.Topolog" +
-      "yId\"\000\0227\n\016RemoveTopology\022\023.context.Topolo" +
-      "gyId\032\016.context.Empty\"\000\022?\n\021GetTopologyEve" +
-      "nts\022\016.context.Empty\032\026.context.TopologyEv" +
-      "ent\"\0000\001\0228\n\rListDeviceIds\022\016.context.Empty" +
-      "\032\025.context.DeviceIdList\"\000\0224\n\013ListDevices" +
-      "\022\016.context.Empty\032\023.context.DeviceList\"\000\022" +
-      "1\n\tGetDevice\022\021.context.DeviceId\032\017.contex" +
-      "t.Device\"\000\0221\n\tSetDevice\022\017.context.Device" +
-      "\032\021.context.DeviceId\"\000\0223\n\014RemoveDevice\022\021." +
-      "context.DeviceId\032\016.context.Empty\"\000\022;\n\017Ge" +
-      "tDeviceEvents\022\016.context.Empty\032\024.context." +
-      "DeviceEvent\"\0000\001\0224\n\013ListLinkIds\022\016.context" +
-      ".Empty\032\023.context.LinkIdList\"\000\0220\n\tListLin" +
-      "ks\022\016.context.Empty\032\021.context.LinkList\"\000\022" +
-      "+\n\007GetLink\022\017.context.LinkId\032\r.context.Li" +
-      "nk\"\000\022+\n\007SetLink\022\r.context.Link\032\017.context" +
-      ".LinkId\"\000\022/\n\nRemoveLink\022\017.context.LinkId" +
-      "\032\016.context.Empty\"\000\0227\n\rGetLinkEvents\022\016.co" +
-      "ntext.Empty\032\022.context.LinkEvent\"\0000\001\022>\n\016L" +
-      "istServiceIds\022\022.context.ContextId\032\026.cont" +
-      "ext.ServiceIdList\"\000\022:\n\014ListServices\022\022.co" +
-      "ntext.ContextId\032\024.context.ServiceList\"\000\022" +
-      "4\n\nGetService\022\022.context.ServiceId\032\020.cont" +
-      "ext.Service\"\000\0224\n\nSetService\022\020.context.Se" +
-      "rvice\032\022.context.ServiceId\"\000\0225\n\rRemoveSer" +
-      "vice\022\022.context.ServiceId\032\016.context.Empty" +
-      "\"\000\022=\n\020GetServiceEvents\022\016.context.Empty\032\025" +
-      ".context.ServiceEvent\"\0000\001\022D\n\021ListConnect" +
-      "ionIds\022\022.context.ServiceId\032\031.context.Con" +
-      "nectionIdList\"\000\022@\n\017ListConnections\022\022.con" +
-      "text.ServiceId\032\027.context.ConnectionList\"" +
-      "\000\022=\n\rGetConnection\022\025.context.ConnectionI" +
-      "d\032\023.context.Connection\"\000\022=\n\rSetConnectio" +
-      "n\022\023.context.Connection\032\025.context.Connect" +
-      "ionId\"\000\022;\n\020RemoveConnection\022\025.context.Co" +
-      "nnectionId\032\016.context.Empty\"\000\022C\n\023GetConne" +
-      "ctionEvents\022\016.context.Empty\032\030.context.Co" +
-      "nnectionEvent\"\0000\001b\006proto3"
+      "Id\"T\n\007SliceId\022&\n\ncontext_id\030\001 \001(\0132\022.cont" +
+      "ext.ContextId\022!\n\nslice_uuid\030\002 \001(\0132\r.cont" +
+      "ext.Uuid\"\225\002\n\005Slice\022\"\n\010slice_id\030\001 \001(\0132\020.c" +
+      "ontext.SliceId\022/\n\022slice_endpoint_ids\030\002 \003" +
+      "(\0132\023.context.EndPointId\022.\n\021slice_constra" +
+      "ints\030\003 \003(\0132\023.context.Constraint\022-\n\021slice" +
+      "_service_ids\030\004 \003(\0132\022.context.ServiceId\022," +
+      "\n\022slice_subslice_ids\030\005 \003(\0132\020.context.Sli" +
+      "ceId\022*\n\014slice_status\030\006 \001(\0132\024.context.Sli" +
+      "ceStatus\"=\n\013SliceStatus\022.\n\014slice_status\030" +
+      "\001 \001(\0162\030.context.SliceStatusEnum\"2\n\013Slice" +
+      "IdList\022#\n\tslice_ids\030\001 \003(\0132\020.context.Slic" +
+      "eId\"+\n\tSliceList\022\036\n\006slices\030\001 \003(\0132\016.conte" +
+      "xt.Slice\"O\n\nSliceEvent\022\035\n\005event\030\001 \001(\0132\016." +
+      "context.Event\022\"\n\010slice_id\030\002 \001(\0132\020.contex" +
+      "t.SliceId\"6\n\014ConnectionId\022&\n\017connection_" +
+      "uuid\030\001 \001(\0132\r.context.Uuid\"\304\001\n\nConnection" +
+      "\022,\n\rconnection_id\030\001 \001(\0132\025.context.Connec" +
+      "tionId\022&\n\nservice_id\030\002 \001(\0132\022.context.Ser" +
+      "viceId\0223\n\026path_hops_endpoint_ids\030\003 \003(\0132\023" +
+      ".context.EndPointId\022+\n\017sub_service_ids\030\004" +
+      " \003(\0132\022.context.ServiceId\"A\n\020ConnectionId" +
+      "List\022-\n\016connection_ids\030\001 \003(\0132\025.context.C" +
+      "onnectionId\":\n\016ConnectionList\022(\n\013connect" +
+      "ions\030\001 \003(\0132\023.context.Connection\"^\n\017Conne" +
+      "ctionEvent\022\035\n\005event\030\001 \001(\0132\016.context.Even" +
+      "t\022,\n\rconnection_id\030\002 \001(\0132\025.context.Conne" +
+      "ctionId\"\202\001\n\nEndPointId\022(\n\013topology_id\030\001 " +
+      "\001(\0132\023.context.TopologyId\022$\n\tdevice_id\030\002 " +
+      "\001(\0132\021.context.DeviceId\022$\n\rendpoint_uuid\030" +
+      "\003 \001(\0132\r.context.Uuid\"\206\001\n\010EndPoint\022(\n\013end" +
+      "point_id\030\001 \001(\0132\023.context.EndPointId\022\025\n\re" +
+      "ndpoint_type\030\002 \001(\t\0229\n\020kpi_sample_types\030\003" +
+      " \003(\0162\037.kpi_sample_types.KpiSampleType\"e\n" +
+      "\nConfigRule\022)\n\006action\030\001 \001(\0162\031.context.Co" +
+      "nfigActionEnum\022\024\n\014resource_key\030\002 \001(\t\022\026\n\016" +
+      "resource_value\030\003 \001(\t\"?\n\nConstraint\022\027\n\017co" +
+      "nstraint_type\030\001 \001(\t\022\030\n\020constraint_value\030" +
+      "\002 \001(\t\"^\n\022TeraFlowController\022&\n\ncontext_i" +
+      "d\030\001 \001(\0132\022.context.ContextId\022\022\n\nip_addres" +
+      "s\030\002 \001(\t\022\014\n\004port\030\003 \001(\r\"U\n\024AuthenticationR" +
+      "esult\022&\n\ncontext_id\030\001 \001(\0132\022.context.Cont" +
+      "extId\022\025\n\rauthenticated\030\002 \001(\010*j\n\rEventTyp" +
+      "eEnum\022\027\n\023EVENTTYPE_UNDEFINED\020\000\022\024\n\020EVENTT" +
+      "YPE_CREATE\020\001\022\024\n\020EVENTTYPE_UPDATE\020\002\022\024\n\020EV" +
+      "ENTTYPE_REMOVE\020\003*\305\001\n\020DeviceDriverEnum\022\032\n" +
+      "\026DEVICEDRIVER_UNDEFINED\020\000\022\033\n\027DEVICEDRIVE" +
+      "R_OPENCONFIG\020\001\022\036\n\032DEVICEDRIVER_TRANSPORT" +
+      "_API\020\002\022\023\n\017DEVICEDRIVER_P4\020\003\022&\n\"DEVICEDRI" +
+      "VER_IETF_NETWORK_TOPOLOGY\020\004\022\033\n\027DEVICEDRI" +
+      "VER_ONF_TR_352\020\005*\217\001\n\033DeviceOperationalSt" +
+      "atusEnum\022%\n!DEVICEOPERATIONALSTATUS_UNDE" +
+      "FINED\020\000\022$\n DEVICEOPERATIONALSTATUS_DISAB" +
+      "LED\020\001\022#\n\037DEVICEOPERATIONALSTATUS_ENABLED" +
+      "\020\002*\201\001\n\017ServiceTypeEnum\022\027\n\023SERVICETYPE_UN" +
+      "KNOWN\020\000\022\024\n\020SERVICETYPE_L3NM\020\001\022\024\n\020SERVICE" +
+      "TYPE_L2NM\020\002\022)\n%SERVICETYPE_TAPI_CONNECTI" +
+      "VITY_SERVICE\020\003*\210\001\n\021ServiceStatusEnum\022\033\n\027" +
+      "SERVICESTATUS_UNDEFINED\020\000\022\031\n\025SERVICESTAT" +
+      "US_PLANNED\020\001\022\030\n\024SERVICESTATUS_ACTIVE\020\002\022!" +
+      "\n\035SERVICESTATUS_PENDING_REMOVAL\020\003*\213\001\n\017Sl" +
+      "iceStatusEnum\022\031\n\025SLICESTATUS_UNDEFINED\020\000" +
+      "\022\027\n\023SLICESTATUS_PLANNED\020\001\022\024\n\020SLICESTATUS" +
+      "_INIT\020\002\022\026\n\022SLICESTATUS_ACTIVE\020\003\022\026\n\022SLICE" +
+      "STATUS_DEINIT\020\004*]\n\020ConfigActionEnum\022\032\n\026C" +
+      "ONFIGACTION_UNDEFINED\020\000\022\024\n\020CONFIGACTION_" +
+      "SET\020\001\022\027\n\023CONFIGACTION_DELETE\020\0022\357\022\n\016Conte" +
+      "xtService\022:\n\016ListContextIds\022\016.context.Em" +
+      "pty\032\026.context.ContextIdList\"\000\0226\n\014ListCon" +
+      "texts\022\016.context.Empty\032\024.context.ContextL" +
+      "ist\"\000\0224\n\nGetContext\022\022.context.ContextId\032" +
+      "\020.context.Context\"\000\0224\n\nSetContext\022\020.cont" +
+      "ext.Context\032\022.context.ContextId\"\000\0225\n\rRem" +
+      "oveContext\022\022.context.ContextId\032\016.context" +
+      ".Empty\"\000\022=\n\020GetContextEvents\022\016.context.E" +
+      "mpty\032\025.context.ContextEvent\"\0000\001\022@\n\017ListT" +
+      "opologyIds\022\022.context.ContextId\032\027.context" +
+      ".TopologyIdList\"\000\022=\n\016ListTopologies\022\022.co" +
+      "ntext.ContextId\032\025.context.TopologyList\"\000" +
+      "\0227\n\013GetTopology\022\023.context.TopologyId\032\021.c" +
+      "ontext.Topology\"\000\0227\n\013SetTopology\022\021.conte" +
+      "xt.Topology\032\023.context.TopologyId\"\000\0227\n\016Re" +
+      "moveTopology\022\023.context.TopologyId\032\016.cont" +
+      "ext.Empty\"\000\022?\n\021GetTopologyEvents\022\016.conte" +
+      "xt.Empty\032\026.context.TopologyEvent\"\0000\001\0228\n\r" +
+      "ListDeviceIds\022\016.context.Empty\032\025.context." +
+      "DeviceIdList\"\000\0224\n\013ListDevices\022\016.context." +
+      "Empty\032\023.context.DeviceList\"\000\0221\n\tGetDevic" +
+      "e\022\021.context.DeviceId\032\017.context.Device\"\000\022" +
+      "1\n\tSetDevice\022\017.context.Device\032\021.context." +
+      "DeviceId\"\000\0223\n\014RemoveDevice\022\021.context.Dev" +
+      "iceId\032\016.context.Empty\"\000\022;\n\017GetDeviceEven" +
+      "ts\022\016.context.Empty\032\024.context.DeviceEvent" +
+      "\"\0000\001\0224\n\013ListLinkIds\022\016.context.Empty\032\023.co" +
+      "ntext.LinkIdList\"\000\0220\n\tListLinks\022\016.contex" +
+      "t.Empty\032\021.context.LinkList\"\000\022+\n\007GetLink\022" +
+      "\017.context.LinkId\032\r.context.Link\"\000\022+\n\007Set" +
+      "Link\022\r.context.Link\032\017.context.LinkId\"\000\022/" +
+      "\n\nRemoveLink\022\017.context.LinkId\032\016.context." +
+      "Empty\"\000\0227\n\rGetLinkEvents\022\016.context.Empty" +
+      "\032\022.context.LinkEvent\"\0000\001\022>\n\016ListServiceI" +
+      "ds\022\022.context.ContextId\032\026.context.Service" +
+      "IdList\"\000\022:\n\014ListServices\022\022.context.Conte" +
+      "xtId\032\024.context.ServiceList\"\000\0224\n\nGetServi" +
+      "ce\022\022.context.ServiceId\032\020.context.Service" +
+      "\"\000\0224\n\nSetService\022\020.context.Service\032\022.con" +
+      "text.ServiceId\"\000\0225\n\rRemoveService\022\022.cont" +
+      "ext.ServiceId\032\016.context.Empty\"\000\022=\n\020GetSe" +
+      "rviceEvents\022\016.context.Empty\032\025.context.Se" +
+      "rviceEvent\"\0000\001\022:\n\014ListSliceIds\022\022.context" +
+      ".ContextId\032\024.context.SliceIdList\"\000\0226\n\nLi" +
+      "stSlices\022\022.context.ContextId\032\022.context.S" +
+      "liceList\"\000\022.\n\010GetSlice\022\020.context.SliceId" +
+      "\032\016.context.Slice\"\000\022.\n\010SetSlice\022\016.context" +
+      ".Slice\032\020.context.SliceId\"\000\0221\n\013RemoveSlic" +
+      "e\022\020.context.SliceId\032\016.context.Empty\"\000\0229\n" +
+      "\016GetSliceEvents\022\016.context.Empty\032\023.contex" +
+      "t.SliceEvent\"\0000\001\022D\n\021ListConnectionIds\022\022." +
+      "context.ServiceId\032\031.context.ConnectionId" +
+      "List\"\000\022@\n\017ListConnections\022\022.context.Serv" +
+      "iceId\032\027.context.ConnectionList\"\000\022=\n\rGetC" +
+      "onnection\022\025.context.ConnectionId\032\023.conte" +
+      "xt.Connection\"\000\022=\n\rSetConnection\022\023.conte" +
+      "xt.Connection\032\025.context.ConnectionId\"\000\022;" +
+      "\n\020RemoveConnection\022\025.context.ConnectionI" +
+      "d\032\016.context.Empty\"\000\022C\n\023GetConnectionEven" +
+      "ts\022\016.context.Empty\032\030.context.ConnectionE" +
+      "vent\"\0000\001b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -38037,68 +44311,104 @@ public final class ContextOuterClass {
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ServiceEvent_descriptor,
         new java.lang.String[] { "Event", "ServiceId", });
-    internal_static_context_ConnectionId_descriptor =
+    internal_static_context_SliceId_descriptor =
       getDescriptor().getMessageTypes().get(31);
+    internal_static_context_SliceId_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceId_descriptor,
+        new java.lang.String[] { "ContextId", "SliceUuid", });
+    internal_static_context_Slice_descriptor =
+      getDescriptor().getMessageTypes().get(32);
+    internal_static_context_Slice_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_Slice_descriptor,
+        new java.lang.String[] { "SliceId", "SliceEndpointIds", "SliceConstraints", "SliceServiceIds", "SliceSubsliceIds", "SliceStatus", });
+    internal_static_context_SliceStatus_descriptor =
+      getDescriptor().getMessageTypes().get(33);
+    internal_static_context_SliceStatus_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceStatus_descriptor,
+        new java.lang.String[] { "SliceStatus", });
+    internal_static_context_SliceIdList_descriptor =
+      getDescriptor().getMessageTypes().get(34);
+    internal_static_context_SliceIdList_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceIdList_descriptor,
+        new java.lang.String[] { "SliceIds", });
+    internal_static_context_SliceList_descriptor =
+      getDescriptor().getMessageTypes().get(35);
+    internal_static_context_SliceList_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceList_descriptor,
+        new java.lang.String[] { "Slices", });
+    internal_static_context_SliceEvent_descriptor =
+      getDescriptor().getMessageTypes().get(36);
+    internal_static_context_SliceEvent_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceEvent_descriptor,
+        new java.lang.String[] { "Event", "SliceId", });
+    internal_static_context_ConnectionId_descriptor =
+      getDescriptor().getMessageTypes().get(37);
     internal_static_context_ConnectionId_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConnectionId_descriptor,
         new java.lang.String[] { "ConnectionUuid", });
     internal_static_context_Connection_descriptor =
-      getDescriptor().getMessageTypes().get(32);
+      getDescriptor().getMessageTypes().get(38);
     internal_static_context_Connection_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_Connection_descriptor,
         new java.lang.String[] { "ConnectionId", "ServiceId", "PathHopsEndpointIds", "SubServiceIds", });
     internal_static_context_ConnectionIdList_descriptor =
-      getDescriptor().getMessageTypes().get(33);
+      getDescriptor().getMessageTypes().get(39);
     internal_static_context_ConnectionIdList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConnectionIdList_descriptor,
         new java.lang.String[] { "ConnectionIds", });
     internal_static_context_ConnectionList_descriptor =
-      getDescriptor().getMessageTypes().get(34);
+      getDescriptor().getMessageTypes().get(40);
     internal_static_context_ConnectionList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConnectionList_descriptor,
         new java.lang.String[] { "Connections", });
     internal_static_context_ConnectionEvent_descriptor =
-      getDescriptor().getMessageTypes().get(35);
+      getDescriptor().getMessageTypes().get(41);
     internal_static_context_ConnectionEvent_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConnectionEvent_descriptor,
         new java.lang.String[] { "Event", "ConnectionId", });
     internal_static_context_EndPointId_descriptor =
-      getDescriptor().getMessageTypes().get(36);
+      getDescriptor().getMessageTypes().get(42);
     internal_static_context_EndPointId_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_EndPointId_descriptor,
         new java.lang.String[] { "TopologyId", "DeviceId", "EndpointUuid", });
     internal_static_context_EndPoint_descriptor =
-      getDescriptor().getMessageTypes().get(37);
+      getDescriptor().getMessageTypes().get(43);
     internal_static_context_EndPoint_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_EndPoint_descriptor,
         new java.lang.String[] { "EndpointId", "EndpointType", "KpiSampleTypes", });
     internal_static_context_ConfigRule_descriptor =
-      getDescriptor().getMessageTypes().get(38);
+      getDescriptor().getMessageTypes().get(44);
     internal_static_context_ConfigRule_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConfigRule_descriptor,
         new java.lang.String[] { "Action", "ResourceKey", "ResourceValue", });
     internal_static_context_Constraint_descriptor =
-      getDescriptor().getMessageTypes().get(39);
+      getDescriptor().getMessageTypes().get(45);
     internal_static_context_Constraint_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_Constraint_descriptor,
         new java.lang.String[] { "ConstraintType", "ConstraintValue", });
     internal_static_context_TeraFlowController_descriptor =
-      getDescriptor().getMessageTypes().get(40);
+      getDescriptor().getMessageTypes().get(46);
     internal_static_context_TeraFlowController_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_TeraFlowController_descriptor,
         new java.lang.String[] { "ContextId", "IpAddress", "Port", });
     internal_static_context_AuthenticationResult_descriptor =
-      getDescriptor().getMessageTypes().get(41);
+      getDescriptor().getMessageTypes().get(47);
     internal_static_context_AuthenticationResult_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_AuthenticationResult_descriptor,
diff --git a/src/policy/target/generated-sources/grpc/context/ContextService.java b/src/policy/target/generated-sources/grpc/context/ContextService.java
index cbd51163f..d54c56057 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextService.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextService.java
@@ -58,6 +58,16 @@ public interface ContextService extends MutinyService {
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request);
     
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request);
+    
     io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request);
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionList> listConnections(context.ContextOuterClass.ServiceId request);
@@ -79,6 +89,8 @@ public interface ContextService extends MutinyService {
     
     io.smallrye.mutiny.Multi<context.ContextOuterClass.ServiceEvent> getServiceEvents(context.ContextOuterClass.Empty request);
     
+    io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request);
+    
     io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request);
     
     
diff --git a/src/policy/target/generated-sources/grpc/context/ContextServiceBean.java b/src/policy/target/generated-sources/grpc/context/ContextServiceBean.java
index 6900cf3c8..f552294b8 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextServiceBean.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextServiceBean.java
@@ -216,6 +216,46 @@ public class ContextServiceBean extends MutinyContextServiceGrpc.ContextServiceI
        }
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request) {
+       try {
+         return delegate.listSliceIds(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request) {
+       try {
+         return delegate.listSlices(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request) {
+       try {
+         return delegate.getSlice(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request) {
+       try {
+         return delegate.setSlice(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
+       try {
+         return delegate.removeSlice(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request) {
        try {
          return delegate.listConnectionIds(request);
@@ -301,6 +341,15 @@ public class ContextServiceBean extends MutinyContextServiceGrpc.ContextServiceI
        }
     }
 
+    @Override
+    public io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request) {
+       try {
+         return delegate.getSliceEvents(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+
     @Override
     public io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request) {
        try {
diff --git a/src/policy/target/generated-sources/grpc/context/ContextServiceClient.java b/src/policy/target/generated-sources/grpc/context/ContextServiceClient.java
index a3d74cb7d..c6493bd4d 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextServiceClient.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextServiceClient.java
@@ -121,6 +121,26 @@ public class ContextServiceClient implements ContextService, MutinyClient<Mutiny
        return stub.removeService(request);
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request) {
+       return stub.listSliceIds(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request) {
+       return stub.listSlices(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request) {
+       return stub.getSlice(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request) {
+       return stub.setSlice(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
+       return stub.removeSlice(request);
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request) {
        return stub.listConnectionIds(request);
     }
@@ -166,6 +186,11 @@ public class ContextServiceClient implements ContextService, MutinyClient<Mutiny
        return stub.getServiceEvents(request);
     }
 
+    @Override
+    public io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request) {
+       return stub.getSliceEvents(request);
+    }
+
     @Override
     public io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request) {
        return stub.getConnectionEvents(request);
diff --git a/src/policy/target/generated-sources/grpc/context/ContextServiceGrpc.java b/src/policy/target/generated-sources/grpc/context/ContextServiceGrpc.java
index be9f381ff..be720c127 100644
--- a/src/policy/target/generated-sources/grpc/context/ContextServiceGrpc.java
+++ b/src/policy/target/generated-sources/grpc/context/ContextServiceGrpc.java
@@ -944,6 +944,192 @@ public final class ContextServiceGrpc {
     return getGetServiceEventsMethod;
   }
 
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId,
+      context.ContextOuterClass.SliceIdList> getListSliceIdsMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "ListSliceIds",
+      requestType = context.ContextOuterClass.ContextId.class,
+      responseType = context.ContextOuterClass.SliceIdList.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId,
+      context.ContextOuterClass.SliceIdList> getListSliceIdsMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId, context.ContextOuterClass.SliceIdList> getListSliceIdsMethod;
+    if ((getListSliceIdsMethod = ContextServiceGrpc.getListSliceIdsMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getListSliceIdsMethod = ContextServiceGrpc.getListSliceIdsMethod) == null) {
+          ContextServiceGrpc.getListSliceIdsMethod = getListSliceIdsMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.ContextId, context.ContextOuterClass.SliceIdList>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ListSliceIds"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.ContextId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceIdList.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("ListSliceIds"))
+              .build();
+        }
+      }
+    }
+    return getListSliceIdsMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId,
+      context.ContextOuterClass.SliceList> getListSlicesMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "ListSlices",
+      requestType = context.ContextOuterClass.ContextId.class,
+      responseType = context.ContextOuterClass.SliceList.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId,
+      context.ContextOuterClass.SliceList> getListSlicesMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId, context.ContextOuterClass.SliceList> getListSlicesMethod;
+    if ((getListSlicesMethod = ContextServiceGrpc.getListSlicesMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getListSlicesMethod = ContextServiceGrpc.getListSlicesMethod) == null) {
+          ContextServiceGrpc.getListSlicesMethod = getListSlicesMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.ContextId, context.ContextOuterClass.SliceList>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ListSlices"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.ContextId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceList.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("ListSlices"))
+              .build();
+        }
+      }
+    }
+    return getListSlicesMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
+      context.ContextOuterClass.Slice> getGetSliceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "GetSlice",
+      requestType = context.ContextOuterClass.SliceId.class,
+      responseType = context.ContextOuterClass.Slice.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
+      context.ContextOuterClass.Slice> getGetSliceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId, context.ContextOuterClass.Slice> getGetSliceMethod;
+    if ((getGetSliceMethod = ContextServiceGrpc.getGetSliceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getGetSliceMethod = ContextServiceGrpc.getGetSliceMethod) == null) {
+          ContextServiceGrpc.getGetSliceMethod = getGetSliceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.SliceId, context.ContextOuterClass.Slice>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetSlice"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Slice.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("GetSlice"))
+              .build();
+        }
+      }
+    }
+    return getGetSliceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Slice,
+      context.ContextOuterClass.SliceId> getSetSliceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "SetSlice",
+      requestType = context.ContextOuterClass.Slice.class,
+      responseType = context.ContextOuterClass.SliceId.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.Slice,
+      context.ContextOuterClass.SliceId> getSetSliceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId> getSetSliceMethod;
+    if ((getSetSliceMethod = ContextServiceGrpc.getSetSliceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getSetSliceMethod = ContextServiceGrpc.getSetSliceMethod) == null) {
+          ContextServiceGrpc.getSetSliceMethod = getSetSliceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetSlice"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Slice.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceId.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("SetSlice"))
+              .build();
+        }
+      }
+    }
+    return getSetSliceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
+      context.ContextOuterClass.Empty> getRemoveSliceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "RemoveSlice",
+      requestType = context.ContextOuterClass.SliceId.class,
+      responseType = context.ContextOuterClass.Empty.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
+      context.ContextOuterClass.Empty> getRemoveSliceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId, context.ContextOuterClass.Empty> getRemoveSliceMethod;
+    if ((getRemoveSliceMethod = ContextServiceGrpc.getRemoveSliceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getRemoveSliceMethod = ContextServiceGrpc.getRemoveSliceMethod) == null) {
+          ContextServiceGrpc.getRemoveSliceMethod = getRemoveSliceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.SliceId, context.ContextOuterClass.Empty>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "RemoveSlice"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Empty.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("RemoveSlice"))
+              .build();
+        }
+      }
+    }
+    return getRemoveSliceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Empty,
+      context.ContextOuterClass.SliceEvent> getGetSliceEventsMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "GetSliceEvents",
+      requestType = context.ContextOuterClass.Empty.class,
+      responseType = context.ContextOuterClass.SliceEvent.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.Empty,
+      context.ContextOuterClass.SliceEvent> getGetSliceEventsMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Empty, context.ContextOuterClass.SliceEvent> getGetSliceEventsMethod;
+    if ((getGetSliceEventsMethod = ContextServiceGrpc.getGetSliceEventsMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getGetSliceEventsMethod = ContextServiceGrpc.getGetSliceEventsMethod) == null) {
+          ContextServiceGrpc.getGetSliceEventsMethod = getGetSliceEventsMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Empty, context.ContextOuterClass.SliceEvent>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetSliceEvents"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Empty.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceEvent.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("GetSliceEvents"))
+              .build();
+        }
+      }
+    }
+    return getGetSliceEventsMethod;
+  }
+
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId,
       context.ContextOuterClass.ConnectionIdList> getListConnectionIdsMethod;
 
@@ -1388,6 +1574,48 @@ public final class ContextServiceGrpc {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetServiceEventsMethod(), responseObserver);
     }
 
+    /**
+     */
+    public void listSliceIds(context.ContextOuterClass.ContextId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceIdList> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getListSliceIdsMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void listSlices(context.ContextOuterClass.ContextId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceList> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getListSlicesMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void getSlice(context.ContextOuterClass.SliceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Slice> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetSliceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void setSlice(context.ContextOuterClass.Slice request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetSliceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void removeSlice(context.ContextOuterClass.SliceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getRemoveSliceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void getSliceEvents(context.ContextOuterClass.Empty request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceEvent> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetSliceEventsMethod(), responseObserver);
+    }
+
     /**
      */
     public void listConnectionIds(context.ContextOuterClass.ServiceId request,
@@ -1642,6 +1870,48 @@ public final class ContextServiceGrpc {
                 context.ContextOuterClass.Empty,
                 context.ContextOuterClass.ServiceEvent>(
                   this, METHODID_GET_SERVICE_EVENTS)))
+          .addMethod(
+            getListSliceIdsMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.ContextId,
+                context.ContextOuterClass.SliceIdList>(
+                  this, METHODID_LIST_SLICE_IDS)))
+          .addMethod(
+            getListSlicesMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.ContextId,
+                context.ContextOuterClass.SliceList>(
+                  this, METHODID_LIST_SLICES)))
+          .addMethod(
+            getGetSliceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.SliceId,
+                context.ContextOuterClass.Slice>(
+                  this, METHODID_GET_SLICE)))
+          .addMethod(
+            getSetSliceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Slice,
+                context.ContextOuterClass.SliceId>(
+                  this, METHODID_SET_SLICE)))
+          .addMethod(
+            getRemoveSliceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.SliceId,
+                context.ContextOuterClass.Empty>(
+                  this, METHODID_REMOVE_SLICE)))
+          .addMethod(
+            getGetSliceEventsMethod(),
+            io.grpc.stub.ServerCalls.asyncServerStreamingCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Empty,
+                context.ContextOuterClass.SliceEvent>(
+                  this, METHODID_GET_SLICE_EVENTS)))
           .addMethod(
             getListConnectionIdsMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -1942,6 +2212,54 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getGetServiceEventsMethod(), getCallOptions()), request, responseObserver);
     }
 
+    /**
+     */
+    public void listSliceIds(context.ContextOuterClass.ContextId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceIdList> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getListSliceIdsMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void listSlices(context.ContextOuterClass.ContextId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceList> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getListSlicesMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void getSlice(context.ContextOuterClass.SliceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Slice> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getGetSliceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void setSlice(context.ContextOuterClass.Slice request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getSetSliceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void removeSlice(context.ContextOuterClass.SliceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getRemoveSliceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void getSliceEvents(context.ContextOuterClass.Empty request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceEvent> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncServerStreamingCall(
+          getChannel().newCall(getGetSliceEventsMethod(), getCallOptions()), request, responseObserver);
+    }
+
     /**
      */
     public void listConnectionIds(context.ContextOuterClass.ServiceId request,
@@ -2220,6 +2538,49 @@ public final class ContextServiceGrpc {
           getChannel(), getGetServiceEventsMethod(), getCallOptions(), request);
     }
 
+    /**
+     */
+    public context.ContextOuterClass.SliceIdList listSliceIds(context.ContextOuterClass.ContextId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getListSliceIdsMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.SliceList listSlices(context.ContextOuterClass.ContextId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getListSlicesMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.Slice getSlice(context.ContextOuterClass.SliceId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getGetSliceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.SliceId setSlice(context.ContextOuterClass.Slice request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getSetSliceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.Empty removeSlice(context.ContextOuterClass.SliceId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getRemoveSliceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public java.util.Iterator<context.ContextOuterClass.SliceEvent> getSliceEvents(
+        context.ContextOuterClass.Empty request) {
+      return io.grpc.stub.ClientCalls.blockingServerStreamingCall(
+          getChannel(), getGetSliceEventsMethod(), getCallOptions(), request);
+    }
+
     /**
      */
     public context.ContextOuterClass.ConnectionIdList listConnectionIds(context.ContextOuterClass.ServiceId request) {
@@ -2478,6 +2839,46 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getRemoveServiceMethod(), getCallOptions()), request);
     }
 
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.SliceIdList> listSliceIds(
+        context.ContextOuterClass.ContextId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getListSliceIdsMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.SliceList> listSlices(
+        context.ContextOuterClass.ContextId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getListSlicesMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Slice> getSlice(
+        context.ContextOuterClass.SliceId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getGetSliceMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.SliceId> setSlice(
+        context.ContextOuterClass.Slice request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getSetSliceMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> removeSlice(
+        context.ContextOuterClass.SliceId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getRemoveSliceMethod(), getCallOptions()), request);
+    }
+
     /**
      */
     public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.ConnectionIdList> listConnectionIds(
@@ -2549,12 +2950,18 @@ public final class ContextServiceGrpc {
   private static final int METHODID_SET_SERVICE = 27;
   private static final int METHODID_REMOVE_SERVICE = 28;
   private static final int METHODID_GET_SERVICE_EVENTS = 29;
-  private static final int METHODID_LIST_CONNECTION_IDS = 30;
-  private static final int METHODID_LIST_CONNECTIONS = 31;
-  private static final int METHODID_GET_CONNECTION = 32;
-  private static final int METHODID_SET_CONNECTION = 33;
-  private static final int METHODID_REMOVE_CONNECTION = 34;
-  private static final int METHODID_GET_CONNECTION_EVENTS = 35;
+  private static final int METHODID_LIST_SLICE_IDS = 30;
+  private static final int METHODID_LIST_SLICES = 31;
+  private static final int METHODID_GET_SLICE = 32;
+  private static final int METHODID_SET_SLICE = 33;
+  private static final int METHODID_REMOVE_SLICE = 34;
+  private static final int METHODID_GET_SLICE_EVENTS = 35;
+  private static final int METHODID_LIST_CONNECTION_IDS = 36;
+  private static final int METHODID_LIST_CONNECTIONS = 37;
+  private static final int METHODID_GET_CONNECTION = 38;
+  private static final int METHODID_SET_CONNECTION = 39;
+  private static final int METHODID_REMOVE_CONNECTION = 40;
+  private static final int METHODID_GET_CONNECTION_EVENTS = 41;
 
   private static final class MethodHandlers<Req, Resp> implements
       io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -2693,6 +3100,30 @@ public final class ContextServiceGrpc {
           serviceImpl.getServiceEvents((context.ContextOuterClass.Empty) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceEvent>) responseObserver);
           break;
+        case METHODID_LIST_SLICE_IDS:
+          serviceImpl.listSliceIds((context.ContextOuterClass.ContextId) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceIdList>) responseObserver);
+          break;
+        case METHODID_LIST_SLICES:
+          serviceImpl.listSlices((context.ContextOuterClass.ContextId) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceList>) responseObserver);
+          break;
+        case METHODID_GET_SLICE:
+          serviceImpl.getSlice((context.ContextOuterClass.SliceId) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Slice>) responseObserver);
+          break;
+        case METHODID_SET_SLICE:
+          serviceImpl.setSlice((context.ContextOuterClass.Slice) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver);
+          break;
+        case METHODID_REMOVE_SLICE:
+          serviceImpl.removeSlice((context.ContextOuterClass.SliceId) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
+          break;
+        case METHODID_GET_SLICE_EVENTS:
+          serviceImpl.getSliceEvents((context.ContextOuterClass.Empty) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceEvent>) responseObserver);
+          break;
         case METHODID_LIST_CONNECTION_IDS:
           serviceImpl.listConnectionIds((context.ContextOuterClass.ServiceId) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.ConnectionIdList>) responseObserver);
@@ -2808,6 +3239,12 @@ public final class ContextServiceGrpc {
               .addMethod(getSetServiceMethod())
               .addMethod(getRemoveServiceMethod())
               .addMethod(getGetServiceEventsMethod())
+              .addMethod(getListSliceIdsMethod())
+              .addMethod(getListSlicesMethod())
+              .addMethod(getGetSliceMethod())
+              .addMethod(getSetSliceMethod())
+              .addMethod(getRemoveSliceMethod())
+              .addMethod(getGetSliceEventsMethod())
               .addMethod(getListConnectionIdsMethod())
               .addMethod(getListConnectionsMethod())
               .addMethod(getGetConnectionMethod())
diff --git a/src/policy/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java b/src/policy/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
index 85abba20a..9f71b5378 100644
--- a/src/policy/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
+++ b/src/policy/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
@@ -161,6 +161,31 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::listSliceIds);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::listSlices);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getSlice);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::setSlice);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::removeSlice);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::listConnectionIds);
         }
@@ -211,6 +236,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::getSliceEvents);
+        }
+
+        
         public io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::getConnectionEvents);
         }
@@ -358,6 +388,31 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
@@ -408,6 +463,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
         public io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
@@ -624,6 +684,48 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                                             context.ContextOuterClass.Empty,
                                             context.ContextOuterClass.ServiceEvent>(
                                             this, METHODID_GET_SERVICE_EVENTS, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getListSliceIdsMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.ContextId,
+                                            context.ContextOuterClass.SliceIdList>(
+                                            this, METHODID_LIST_SLICE_IDS, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getListSlicesMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.ContextId,
+                                            context.ContextOuterClass.SliceList>(
+                                            this, METHODID_LIST_SLICES, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getGetSliceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.SliceId,
+                                            context.ContextOuterClass.Slice>(
+                                            this, METHODID_GET_SLICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getSetSliceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Slice,
+                                            context.ContextOuterClass.SliceId>(
+                                            this, METHODID_SET_SLICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getRemoveSliceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.SliceId,
+                                            context.ContextOuterClass.Empty>(
+                                            this, METHODID_REMOVE_SLICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getGetSliceEventsMethod(),
+                            asyncServerStreamingCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Empty,
+                                            context.ContextOuterClass.SliceEvent>(
+                                            this, METHODID_GET_SLICE_EVENTS, compression)))
                     .addMethod(
                             context.ContextServiceGrpc.getListConnectionIdsMethod(),
                             asyncUnaryCall(
@@ -700,12 +802,18 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
     private static final int METHODID_SET_SERVICE = 27;
     private static final int METHODID_REMOVE_SERVICE = 28;
     private static final int METHODID_GET_SERVICE_EVENTS = 29;
-    private static final int METHODID_LIST_CONNECTION_IDS = 30;
-    private static final int METHODID_LIST_CONNECTIONS = 31;
-    private static final int METHODID_GET_CONNECTION = 32;
-    private static final int METHODID_SET_CONNECTION = 33;
-    private static final int METHODID_REMOVE_CONNECTION = 34;
-    private static final int METHODID_GET_CONNECTION_EVENTS = 35;
+    private static final int METHODID_LIST_SLICE_IDS = 30;
+    private static final int METHODID_LIST_SLICES = 31;
+    private static final int METHODID_GET_SLICE = 32;
+    private static final int METHODID_SET_SLICE = 33;
+    private static final int METHODID_REMOVE_SLICE = 34;
+    private static final int METHODID_GET_SLICE_EVENTS = 35;
+    private static final int METHODID_LIST_CONNECTION_IDS = 36;
+    private static final int METHODID_LIST_CONNECTIONS = 37;
+    private static final int METHODID_GET_CONNECTION = 38;
+    private static final int METHODID_SET_CONNECTION = 39;
+    private static final int METHODID_REMOVE_CONNECTION = 40;
+    private static final int METHODID_GET_CONNECTION_EVENTS = 41;
 
     private static final class MethodHandlers<Req, Resp> implements
             io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -906,6 +1014,42 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                             compression,
                             serviceImpl::getServiceEvents);
                     break;
+                case METHODID_LIST_SLICE_IDS:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ContextId) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceIdList>) responseObserver,
+                            compression,
+                            serviceImpl::listSliceIds);
+                    break;
+                case METHODID_LIST_SLICES:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ContextId) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceList>) responseObserver,
+                            compression,
+                            serviceImpl::listSlices);
+                    break;
+                case METHODID_GET_SLICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.SliceId) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Slice>) responseObserver,
+                            compression,
+                            serviceImpl::getSlice);
+                    break;
+                case METHODID_SET_SLICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Slice) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver,
+                            compression,
+                            serviceImpl::setSlice);
+                    break;
+                case METHODID_REMOVE_SLICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.SliceId) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
+                            compression,
+                            serviceImpl::removeSlice);
+                    break;
+                case METHODID_GET_SLICE_EVENTS:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToMany((context.ContextOuterClass.Empty) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceEvent>) responseObserver,
+                            compression,
+                            serviceImpl::getSliceEvents);
+                    break;
                 case METHODID_LIST_CONNECTION_IDS:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ServiceId) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.ConnectionIdList>) responseObserver,
diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml
index 269478f97..9e37a5e46 100644
--- a/src/policy/target/kubernetes/kubernetes.yml
+++ b/src/policy/target/kubernetes/kubernetes.yml
@@ -17,20 +17,20 @@ apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 43bda7817c976a9fb8ed7a410ad4f0ea13f62498
-    app.quarkus.io/build-timestamp: 2022-02-15 - 14:44:53 +0000
+    app.quarkus.io/commit-id: 2dc4ceff96a6d340debf25cc3faa9c7ce1fb145d
+    app.quarkus.io/build-timestamp: 2022-05-23 - 11:03:33 +0000
   labels:
     app.kubernetes.io/name: policyservice
     app: policyservice
   name: policyservice
 spec:
   ports:
-    - name: grpc-server
-      port: 9999
-      targetPort: 9999
     - name: http
       port: 8080
       targetPort: 8080
+    - name: grpc-server
+      port: 9999
+      targetPort: 9999
   selector:
     app.kubernetes.io/name: policyservice
   type: ClusterIP
@@ -39,8 +39,8 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 43bda7817c976a9fb8ed7a410ad4f0ea13f62498
-    app.quarkus.io/build-timestamp: 2022-02-15 - 14:44:53 +0000
+    app.quarkus.io/commit-id: 2dc4ceff96a6d340debf25cc3faa9c7ce1fb145d
+    app.quarkus.io/build-timestamp: 2022-05-23 - 11:03:33 +0000
   labels:
     app: policyservice
     app.kubernetes.io/name: policyservice
@@ -53,8 +53,8 @@ spec:
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: 43bda7817c976a9fb8ed7a410ad4f0ea13f62498
-        app.quarkus.io/build-timestamp: 2022-02-15 - 14:44:53 +0000
+        app.quarkus.io/commit-id: 2dc4ceff96a6d340debf25cc3faa9c7ce1fb145d
+        app.quarkus.io/build-timestamp: 2022-05-23 - 11:03:33 +0000
       labels:
         app: policyservice
         app.kubernetes.io/name: policyservice
@@ -73,25 +73,25 @@ spec:
               path: /q/health/live
               port: 8080
               scheme: HTTP
-            initialDelaySeconds: 5
-            periodSeconds: 45
+            initialDelaySeconds: 2
+            periodSeconds: 10
             successThreshold: 1
             timeoutSeconds: 10
           name: policyservice
           ports:
-            - containerPort: 9999
-              name: grpc-server
-              protocol: TCP
             - containerPort: 8080
               name: http
               protocol: TCP
+            - containerPort: 9999
+              name: grpc-server
+              protocol: TCP
           readinessProbe:
             failureThreshold: 3
             httpGet:
               path: /q/health/ready
               port: 8080
               scheme: HTTP
-            initialDelaySeconds: 5
-            periodSeconds: 45
+            initialDelaySeconds: 2
+            periodSeconds: 10
             successThreshold: 1
             timeoutSeconds: 10
-- 
GitLab


From 7940a47dc7408bc3228c6d8aeec0c49a8ef3c177 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Mon, 23 May 2022 16:58:07 +0300
Subject: [PATCH 40/60] style(policy): file formatting

---
 .../eu/teraflow/policy/PolicyGateway.java     | 28 +++++++++----------
 .../eu/teraflow/policy/PolicyGatewayImpl.java | 28 +++++++++----------
 .../eu/teraflow/policy/PolicyService.java     | 28 +++++++++----------
 .../eu/teraflow/policy/PolicyServiceImpl.java | 28 +++++++++----------
 .../teraflow/policy/SimpleLivenessCheck.java  | 28 +++++++++----------
 .../policy/context/ContextService.java        | 28 +++++++++----------
 .../policy/context/model/ContextId.java       | 28 +++++++++----------
 .../policy/context/model/DeviceId.java        | 28 +++++++++----------
 .../teraflow/policy/context/model/Event.java  | 28 +++++++++----------
 .../policy/context/model/EventTypeEnum.java   | 28 +++++++++----------
 .../policy/context/model/ServiceId.java       | 28 +++++++++----------
 .../teraflow/policy/context/model/Uuid.java   | 28 +++++++++----------
 .../eu/teraflow/policy/model/PolicyRule.java  | 28 +++++++++----------
 .../policy/model/PolicyRuleAction.java        | 28 +++++++++----------
 .../policy/model/PolicyRuleCondition.java     | 28 +++++++++----------
 .../policy/model/PolicyRuleEvent.java         | 28 +++++++++----------
 .../teraflow/policy/model/PolicyRuleId.java   | 28 +++++++++----------
 .../policy/model/PolicyRulePriority.java      | 28 +++++++++----------
 .../policy/model/PolicyRuleState.java         | 28 +++++++++----------
 .../teraflow/policy/model/PolicyRuleType.java | 28 +++++++++----------
 .../policy/model/PolicyRuleValue.java         | 28 +++++++++----------
 .../policy/model/PolicyRuleVariable.java      | 28 +++++++++----------
 .../eu/teraflow/policy/model/RuleState.java   | 28 +++++++++----------
 .../eu/teraflow/policy/PolicyServiceTest.java | 28 +++++++++----------
 src/policy/target/kubernetes/kubernetes.yml   | 26 ++++-------------
 25 files changed, 342 insertions(+), 356 deletions(-)

diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyGateway.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyGateway.java
index b6d1de94a..2e8f9bba4 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/PolicyGateway.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyGateway.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java
index 45eed4c91..b95271708 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyService.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyService.java
index 5659fd61b..d20775cc1 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/PolicyService.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyService.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java
index 4b8ceba90..d8025d080 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/SimpleLivenessCheck.java b/src/policy/src/main/java/eu/teraflow/policy/SimpleLivenessCheck.java
index 3b60e1ad7..a4e556313 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/SimpleLivenessCheck.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/SimpleLivenessCheck.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/ContextService.java b/src/policy/src/main/java/eu/teraflow/policy/context/ContextService.java
index f8803f514..4d2b317cb 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/ContextService.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/ContextService.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.context;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/ContextId.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/ContextId.java
index c5c222942..47bcf543e 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/ContextId.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/ContextId.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.context.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceId.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceId.java
index af82cd4d4..4277bf693 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceId.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceId.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.context.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/Event.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/Event.java
index 309f8e077..a9d532e06 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/Event.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/Event.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.context.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/EventTypeEnum.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/EventTypeEnum.java
index 30b890e60..2a45a89a7 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/EventTypeEnum.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/EventTypeEnum.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.context.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceId.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceId.java
index 3680cb5ef..e8027d82c 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceId.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceId.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.context.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/Uuid.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/Uuid.java
index 857f7a51a..9a429f5ac 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/Uuid.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/Uuid.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.context.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java
index d9f597405..20f78eb81 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleAction.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleAction.java
index d3a3fd036..8592262ae 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleAction.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleAction.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java
index 8f7b74e3f..22d65124c 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java
index c5660b95d..476d19482 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleId.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleId.java
index e3a25557a..cc95d9e5d 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleId.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleId.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRulePriority.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRulePriority.java
index 7113a20fa..c85bb9a36 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRulePriority.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRulePriority.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleState.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleState.java
index 465187a5f..43b934030 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleState.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleState.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java
index 1b46b249e..6becad243 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleValue.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleValue.java
index 2e6498f23..9a928c4a2 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleValue.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleValue.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleVariable.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleVariable.java
index 10f86bbca..fa35d270a 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleVariable.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleVariable.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/RuleState.java b/src/policy/src/main/java/eu/teraflow/policy/model/RuleState.java
index 05e051348..6c8aabdb0 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/RuleState.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/RuleState.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy.model;
 
diff --git a/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java b/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java
index abb9bdd36..47a5502d1 100644
--- a/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java
+++ b/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.policy;
 
diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml
index 9e37a5e46..3625e9d85 100644
--- a/src/policy/target/kubernetes/kubernetes.yml
+++ b/src/policy/target/kubernetes/kubernetes.yml
@@ -1,24 +1,10 @@
-# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
 ---
 apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 2dc4ceff96a6d340debf25cc3faa9c7ce1fb145d
-    app.quarkus.io/build-timestamp: 2022-05-23 - 11:03:33 +0000
+    app.quarkus.io/commit-id: 54b760b9045db694a08b0f291f52b28aa4d8c5d2
+    app.quarkus.io/build-timestamp: 2022-05-23 - 13:57:10 +0000
   labels:
     app.kubernetes.io/name: policyservice
     app: policyservice
@@ -39,8 +25,8 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 2dc4ceff96a6d340debf25cc3faa9c7ce1fb145d
-    app.quarkus.io/build-timestamp: 2022-05-23 - 11:03:33 +0000
+    app.quarkus.io/commit-id: 54b760b9045db694a08b0f291f52b28aa4d8c5d2
+    app.quarkus.io/build-timestamp: 2022-05-23 - 13:57:10 +0000
   labels:
     app: policyservice
     app.kubernetes.io/name: policyservice
@@ -53,8 +39,8 @@ spec:
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: 2dc4ceff96a6d340debf25cc3faa9c7ce1fb145d
-        app.quarkus.io/build-timestamp: 2022-05-23 - 11:03:33 +0000
+        app.quarkus.io/commit-id: 54b760b9045db694a08b0f291f52b28aa4d8c5d2
+        app.quarkus.io/build-timestamp: 2022-05-23 - 13:57:10 +0000
       labels:
         app: policyservice
         app.kubernetes.io/name: policyservice
-- 
GitLab


From 521616fd81cc4cb1821a45ef8ff13e88c29dd6c6 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Mon, 23 May 2022 17:05:58 +0300
Subject: [PATCH 41/60] chore(policy): modify Dockerfile to run coverage

---
 src/policy/src/main/docker/Dockerfile.multistage.jvm | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/policy/src/main/docker/Dockerfile.multistage.jvm b/src/policy/src/main/docker/Dockerfile.multistage.jvm
index 280e4142d..e153b7d84 100644
--- a/src/policy/src/main/docker/Dockerfile.multistage.jvm
+++ b/src/policy/src/main/docker/Dockerfile.multistage.jvm
@@ -29,7 +29,7 @@ RUN mvn --errors --batch-mode package -Dmaven.test.skip=true
 # Stage 2
 FROM builder AS unit-test
 
-RUN mvn --errors --batch-mode test
+RUN mvn --errors --batch-mode -Pgenerate-consolidated-coverage verify
 
 # Stage 3
 FROM registry.access.redhat.com/ubi8/ubi-minimal:8.4 AS release
-- 
GitLab


From 3e2020a54303e366b072f2af2e47d2e1859feaf7 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Tue, 31 May 2022 10:35:08 +0300
Subject: [PATCH 42/60] chore(policy): add bouncycastle dependency to pom.xml

---
 src/policy/pom.xml | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/src/policy/pom.xml b/src/policy/pom.xml
index 02077d79a..6233d3edb 100644
--- a/src/policy/pom.xml
+++ b/src/policy/pom.xml
@@ -99,6 +99,12 @@
     </dependencyManagement>
 
     <dependencies>
+        <dependency>
+            <groupId>io.github.project-openubl</groupId>
+            <artifactId>quarkus-bouncycastle</artifactId>
+            <version>1.2.2.Final</version>
+        </dependency>
+        
         <dependency>
             <groupId>io.quarkus</groupId>
             <artifactId>quarkus-grpc</artifactId>
-- 
GitLab


From c420b15ef68dd750adc20659ff6c7a6c00ef127f Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Tue, 31 May 2022 17:17:36 +0300
Subject: [PATCH 43/60] chore: activate CI for Policy component

---
 .gitlab-ci.yml | 1 +
 1 file changed, 1 insertion(+)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index e47c3f461..615872734 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -34,6 +34,7 @@ include:
   - local: '/src/opticalattackmitigator/.gitlab-ci.yml'
   - local: '/src/opticalcentralizedattackdetector/.gitlab-ci.yml'
   - local: '/src/automation/.gitlab-ci.yml'
+  - local: '/src/policy/.gitlab-ci.yml'
   #- local: '/src/webui/.gitlab-ci.yml'
   #- local: '/src/l3_distributedattackdetector/.gitlab-ci.yml'
   #- local: '/src/l3_centralizedattackdetector/.gitlab-ci.yml'
-- 
GitLab


From a0bfc2c8bcfb703ec2123598251b68fdf07221da Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Wed, 1 Jun 2022 15:56:13 +0300
Subject: [PATCH 44/60] feat(policy): add readiness health check

---
 .../teraflow/policy/SimpleLivenessCheck.java  |  2 +-
 .../teraflow/policy/SimpleReadinessCheck.java | 32 +++++++++++++++++++
 2 files changed, 33 insertions(+), 1 deletion(-)
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/SimpleReadinessCheck.java

diff --git a/src/policy/src/main/java/eu/teraflow/policy/SimpleLivenessCheck.java b/src/policy/src/main/java/eu/teraflow/policy/SimpleLivenessCheck.java
index a4e556313..bee4157d0 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/SimpleLivenessCheck.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/SimpleLivenessCheck.java
@@ -27,6 +27,6 @@ public class SimpleLivenessCheck implements HealthCheck {
 
     @Override
     public HealthCheckResponse call() {
-        return HealthCheckResponse.up("Policy Service");
+        return HealthCheckResponse.up("Policy Service is live");
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/SimpleReadinessCheck.java b/src/policy/src/main/java/eu/teraflow/policy/SimpleReadinessCheck.java
new file mode 100644
index 000000000..0fe0c43b0
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/SimpleReadinessCheck.java
@@ -0,0 +1,32 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy;
+
+import javax.enterprise.context.ApplicationScoped;
+import org.eclipse.microprofile.health.HealthCheck;
+import org.eclipse.microprofile.health.HealthCheckResponse;
+import org.eclipse.microprofile.health.Readiness;
+
+@Readiness
+@ApplicationScoped
+public class SimpleReadinessCheck implements HealthCheck {
+
+    @Override
+    public HealthCheckResponse call() {
+        return HealthCheckResponse.up("Policy Service is ready");
+    }
+}
-- 
GitLab


From 783dfb0f6787bcc8b65d5471df5be38a005b9a7e Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Fri, 27 May 2022 11:06:47 +0300
Subject: [PATCH 45/60] style(automation): remove code smells and format code

---
 .../automation/AutomationConfiguration.java   |   28 +-
 .../automation/AutomationGateway.java         |   28 +-
 .../automation/AutomationGatewayImpl.java     |   37 +-
 .../automation/AutomationService.java         |   28 +-
 .../automation/AutomationServiceImpl.java     |   28 +-
 .../automation/ContextSubscriber.java         |   28 +-
 .../eu/teraflow/automation/Serializer.java    |   28 +-
 .../automation/SimpleLivenessCheck.java       |   28 +-
 .../automation/SimpleReadinessCheck.java      |   28 +-
 .../automation/context/ContextGateway.java    |   28 +-
 .../context/ContextGatewayImpl.java           |   32 +-
 .../automation/context/ContextService.java    |   28 +-
 .../context/ContextServiceImpl.java           |   28 +-
 .../automation/context/model/Event.java       |   28 +-
 .../context/model/EventTypeEnum.java          |   28 +-
 .../automation/device/DeviceGateway.java      |   28 +-
 .../automation/device/DeviceGatewayImpl.java  |   31 +-
 .../automation/device/DeviceService.java      |   28 +-
 .../automation/device/DeviceServiceImpl.java  |   28 +-
 .../device/model/ConfigActionEnum.java        |   28 +-
 .../automation/device/model/ConfigRule.java   |   28 +-
 .../automation/device/model/Device.java       |   28 +-
 .../automation/device/model/DeviceConfig.java |   28 +-
 .../automation/device/model/DeviceEvent.java  |   28 +-
 .../device/model/DeviceOperationalStatus.java |   28 +-
 .../teraflow/automation/model/DeviceRole.java |   28 +-
 .../automation/model/DeviceRoleId.java        |   28 +-
 .../automation/model/DeviceRoleType.java      |   28 +-
 .../automation/model/DeviceState.java         |   28 +-
 .../automation/AutomationServiceTest.java     |   38 +-
 .../teraflow/automation/SerializerTest.java   |   62 +-
 .../grpc/context/ContextOuterClass.java       | 6714 ++++++++++++++++-
 .../grpc/context/ContextService.java          |   12 +
 .../grpc/context/ContextServiceBean.java      |   49 +
 .../grpc/context/ContextServiceClient.java    |   25 +
 .../grpc/context/ContextServiceGrpc.java      |  449 +-
 .../context/MutinyContextServiceGrpc.java     |  156 +-
 .../target/kubernetes/kubernetes.yml          |   44 +-
 38 files changed, 7672 insertions(+), 705 deletions(-)

diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationConfiguration.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationConfiguration.java
index 55f5cce25..91b6e159d 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationConfiguration.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationConfiguration.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationGateway.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationGateway.java
index 1533643d1..2d8194c69 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationGateway.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationGateway.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java
index 7f403459a..7a68965bf 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationGatewayImpl.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
@@ -56,7 +56,7 @@ public class AutomationGatewayImpl implements AutomationGateway {
         return automationService
                 .addDevice(deviceId)
                 .onItem()
-                .transform( device -> transformToDeviceRoleState(device, devRoleId));
+                .transform(device -> transformToDeviceRoleState(device, devRoleId));
     }
 
     @Override
@@ -84,8 +84,9 @@ public class AutomationGatewayImpl implements AutomationGateway {
         return Uni.createFrom().item(() -> Automation.DeviceDeletionResult.newBuilder().build());
     }
 
-    // TODO When `DeviceRoleState` domain object will be created, move this method to Serializer class and create related tests
-    private Automation.DeviceRoleState transformToDeviceRoleState(Device device, String devRoleId){
+    // TODO When `DeviceRoleState` domain object will be created, move this method to Serializer class
+    // and create related tests
+    private Automation.DeviceRoleState transformToDeviceRoleState(Device device, String devRoleId) {
 
         final var deviceRoleId = new DeviceRoleId(devRoleId, device.getDeviceId());
         final var serializeDeviceRoleId = serializer.serialize(deviceRoleId);
@@ -95,4 +96,4 @@ public class AutomationGatewayImpl implements AutomationGateway {
                 .setDevRoleState(Automation.ZtpDeviceState.ZTP_DEV_STATE_CREATED)
                 .build();
     }
-}
\ No newline at end of file
+}
diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java
index 38d7420ed..9e8927d58 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationService.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java b/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java
index 433dffbc7..3db0d647e 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/AutomationServiceImpl.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java b/src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java
index cb80a6428..c27a2a844 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/ContextSubscriber.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/Serializer.java b/src/automation/src/main/java/eu/teraflow/automation/Serializer.java
index 1cabde5bf..78f251439 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/Serializer.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/Serializer.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/SimpleLivenessCheck.java b/src/automation/src/main/java/eu/teraflow/automation/SimpleLivenessCheck.java
index 056b844d5..7c3a2ccb5 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/SimpleLivenessCheck.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/SimpleLivenessCheck.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/SimpleReadinessCheck.java b/src/automation/src/main/java/eu/teraflow/automation/SimpleReadinessCheck.java
index ef1b4c4ef..c863a6c28 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/SimpleReadinessCheck.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/SimpleReadinessCheck.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/ContextGateway.java b/src/automation/src/main/java/eu/teraflow/automation/context/ContextGateway.java
index 83bcc1afd..3bae4161d 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/ContextGateway.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/ContextGateway.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.context;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/ContextGatewayImpl.java b/src/automation/src/main/java/eu/teraflow/automation/context/ContextGatewayImpl.java
index 1b11d09a4..7bec64138 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/ContextGatewayImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/ContextGatewayImpl.java
@@ -1,36 +1,34 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.context;
 
 import context.ContextOuterClass;
 import context.MutinyContextServiceGrpc.MutinyContextServiceStub;
 import eu.teraflow.automation.Serializer;
-import eu.teraflow.automation.device.model.*;
 import eu.teraflow.automation.device.model.Device;
+import eu.teraflow.automation.device.model.DeviceEvent;
 import io.quarkus.grpc.GrpcClient;
 import io.smallrye.mutiny.Multi;
 import io.smallrye.mutiny.Uni;
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
-import org.jboss.logging.Logger;
 
 @ApplicationScoped
 public class ContextGatewayImpl implements ContextGateway {
-    private static final Logger LOGGER = Logger.getLogger(ContextGatewayImpl.class);
 
     @GrpcClient("context")
     MutinyContextServiceStub streamingDelegateContext;
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/ContextService.java b/src/automation/src/main/java/eu/teraflow/automation/context/ContextService.java
index 8b690782a..c3e01a125 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/ContextService.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/ContextService.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.context;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/ContextServiceImpl.java b/src/automation/src/main/java/eu/teraflow/automation/context/ContextServiceImpl.java
index 38a938833..10d16bdf9 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/ContextServiceImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/ContextServiceImpl.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.context;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/model/Event.java b/src/automation/src/main/java/eu/teraflow/automation/context/model/Event.java
index 974d8dc93..2b4a4bab6 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/model/Event.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/model/Event.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.context.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/context/model/EventTypeEnum.java b/src/automation/src/main/java/eu/teraflow/automation/context/model/EventTypeEnum.java
index 4c723b298..38c2cd3f0 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/context/model/EventTypeEnum.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/context/model/EventTypeEnum.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.context.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/DeviceGateway.java b/src/automation/src/main/java/eu/teraflow/automation/device/DeviceGateway.java
index 6a285c14c..41a7d18f5 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/DeviceGateway.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/DeviceGateway.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/DeviceGatewayImpl.java b/src/automation/src/main/java/eu/teraflow/automation/device/DeviceGatewayImpl.java
index e10bd5ee0..00270e478 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/DeviceGatewayImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/DeviceGatewayImpl.java
@@ -1,22 +1,21 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device;
 
-import context.ContextOuterClass;
 import device.DeviceService;
 import eu.teraflow.automation.Serializer;
 import eu.teraflow.automation.device.model.Device;
@@ -25,11 +24,9 @@ import io.quarkus.grpc.GrpcClient;
 import io.smallrye.mutiny.Uni;
 import javax.enterprise.context.ApplicationScoped;
 import javax.inject.Inject;
-import org.jboss.logging.Logger;
 
 @ApplicationScoped
 public class DeviceGatewayImpl implements DeviceGateway {
-    private static final Logger LOGGER = Logger.getLogger(DeviceGatewayImpl.class);
 
     @GrpcClient("device")
     DeviceService deviceDelegate;
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/DeviceService.java b/src/automation/src/main/java/eu/teraflow/automation/device/DeviceService.java
index 1d982bbd5..0be0688b5 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/DeviceService.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/DeviceService.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/DeviceServiceImpl.java b/src/automation/src/main/java/eu/teraflow/automation/device/DeviceServiceImpl.java
index 992c9e07a..f58c03ee7 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/DeviceServiceImpl.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/DeviceServiceImpl.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/model/ConfigActionEnum.java b/src/automation/src/main/java/eu/teraflow/automation/device/model/ConfigActionEnum.java
index 103703c22..bbe8d5916 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/model/ConfigActionEnum.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/model/ConfigActionEnum.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/model/ConfigRule.java b/src/automation/src/main/java/eu/teraflow/automation/device/model/ConfigRule.java
index b419984b7..d307463d1 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/model/ConfigRule.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/model/ConfigRule.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/model/Device.java b/src/automation/src/main/java/eu/teraflow/automation/device/model/Device.java
index 1cd0f9c32..b5dbae626 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/model/Device.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/model/Device.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceConfig.java b/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceConfig.java
index 68248136a..6365b0ed9 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceConfig.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceConfig.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceEvent.java b/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceEvent.java
index 6589e224e..5a021276c 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceEvent.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceEvent.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceOperationalStatus.java b/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceOperationalStatus.java
index 397c5276c..163b34704 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceOperationalStatus.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/device/model/DeviceOperationalStatus.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.device.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRole.java b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRole.java
index fb538fee2..6dffcd1c0 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRole.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRole.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleId.java b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleId.java
index d0b7e6a2a..b11f42ad0 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleId.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleId.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleType.java b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleType.java
index e92c88c4a..8d55e0cb4 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleType.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceRoleType.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.model;
 
diff --git a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceState.java b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceState.java
index 53a6b2712..48bc37ef7 100644
--- a/src/automation/src/main/java/eu/teraflow/automation/model/DeviceState.java
+++ b/src/automation/src/main/java/eu/teraflow/automation/model/DeviceState.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation.model;
 
diff --git a/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java b/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java
index 56c274321..b1178e2dd 100644
--- a/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java
+++ b/src/automation/src/test/java/eu/teraflow/automation/AutomationServiceTest.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
@@ -20,13 +20,15 @@ import static org.assertj.core.api.Assertions.assertThat;
 
 import automation.Automation;
 import automation.AutomationService;
-import context.ContextOuterClass;
-import eu.teraflow.automation.model.DeviceRole;
-import eu.teraflow.automation.model.DeviceRoleId;
 import eu.teraflow.automation.context.ContextGateway;
 import eu.teraflow.automation.device.DeviceGateway;
-import eu.teraflow.automation.device.model.*;
+import eu.teraflow.automation.device.model.ConfigActionEnum;
+import eu.teraflow.automation.device.model.ConfigRule;
 import eu.teraflow.automation.device.model.Device;
+import eu.teraflow.automation.device.model.DeviceConfig;
+import eu.teraflow.automation.device.model.DeviceOperationalStatus;
+import eu.teraflow.automation.model.DeviceRole;
+import eu.teraflow.automation.model.DeviceRoleId;
 import eu.teraflow.automation.model.DeviceRoleType;
 import io.quarkus.grpc.GrpcClient;
 import io.quarkus.test.junit.QuarkusTest;
diff --git a/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java b/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java
index 4d4a57da7..ff7414854 100644
--- a/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java
+++ b/src/automation/src/test/java/eu/teraflow/automation/SerializerTest.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
@@ -53,7 +53,8 @@ class SerializerTest {
         final var expectedDeviceId = "expectedDeviceId";
 
         final var deviceIdUuid = serializer.serializeUuid(expectedDeviceId);
-        final var deviceId = ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(deviceIdUuid).build();
+        final var deviceId =
+                ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(deviceIdUuid).build();
 
         final var serializedDeviceId = serializer.serializeDeviceId(expectedDeviceId);
 
@@ -65,7 +66,8 @@ class SerializerTest {
         final var expectedDeviceId = "expectedDeviceId";
 
         final var serializedDeviceIdUuid = serializer.serializeUuid("expectedDeviceId");
-        final var serializedDeviceId = DeviceId.newBuilder().setDeviceUuid(serializedDeviceIdUuid).build();
+        final var serializedDeviceId =
+                DeviceId.newBuilder().setDeviceUuid(serializedDeviceIdUuid).build();
 
         final var deviceId = serializer.deserialize(serializedDeviceId);
 
@@ -80,7 +82,10 @@ class SerializerTest {
         final var deviceRoleId = new DeviceRoleId(expectedDevRoleId, expectedDeviceId);
         final var serializedDeviceRoleIdUuid = serializer.serializeUuid(expectedDevRoleId);
         final var serializedDeviceRoleDeviceIdUuid = serializer.serializeUuid(expectedDeviceId);
-        final var serializedDeviceRoleDeviceId = ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(serializedDeviceRoleDeviceIdUuid).build();
+        final var serializedDeviceRoleDeviceId =
+                ContextOuterClass.DeviceId.newBuilder()
+                        .setDeviceUuid(serializedDeviceRoleDeviceIdUuid)
+                        .build();
 
         final var expectedDeviceRoleId =
                 Automation.DeviceRoleId.newBuilder()
@@ -88,8 +93,7 @@ class SerializerTest {
                         .setDevId(serializedDeviceRoleDeviceId)
                         .build();
 
-        final var serializedDevRoleId =
-                serializer.serialize(deviceRoleId);
+        final var serializedDevRoleId = serializer.serialize(deviceRoleId);
 
         assertThat(serializedDevRoleId).usingRecursiveComparison().isEqualTo(expectedDeviceRoleId);
     }
@@ -142,19 +146,21 @@ class SerializerTest {
         final var serializedDeviceRoleDevRoleIdUuid = serializer.serializeUuid(expectedDevRoleId);
         final var serializedDeviceRoleDeviceId = serializer.serializeDeviceId(expectedDeviceId);
 
-        final var expectedDeviceRoleId = Automation.DeviceRoleId.newBuilder()
-                .setDevRoleId(serializedDeviceRoleDevRoleIdUuid)
-                .setDevId(serializedDeviceRoleDeviceId)
-                .build();
+        final var expectedDeviceRoleId =
+                Automation.DeviceRoleId.newBuilder()
+                        .setDevRoleId(serializedDeviceRoleDevRoleIdUuid)
+                        .setDevId(serializedDeviceRoleDeviceId)
+                        .build();
 
         final var expectedDeviceRoleType = Automation.DeviceRoleType.PIPELINE_CONF;
 
-        final var expectedDeviceRole = Automation.DeviceRole.newBuilder()
-                .setDevRoleId(expectedDeviceRoleId)
-                .setDevRoleType(expectedDeviceRoleType)
-                .build();
+        final var expectedDeviceRole =
+                Automation.DeviceRole.newBuilder()
+                        .setDevRoleId(expectedDeviceRoleId)
+                        .setDevRoleType(expectedDeviceRoleType)
+                        .build();
 
-        final var deviceRoleId = new DeviceRoleId(expectedDevRoleId,expectedDeviceId);
+        final var deviceRoleId = new DeviceRoleId(expectedDevRoleId, expectedDeviceId);
         final var deviceRoleType = DeviceRoleType.PIPELINE_CONF;
 
         final var deviceRole = new DeviceRole(deviceRoleId, deviceRoleType);
diff --git a/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java b/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java
index 168ddf78b..ee807d7a7 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextOuterClass.java
@@ -661,6 +661,141 @@ public final class ContextOuterClass {
     // @@protoc_insertion_point(enum_scope:context.ServiceStatusEnum)
   }
 
+  /**
+   * Protobuf enum {@code context.SliceStatusEnum}
+   */
+  public enum SliceStatusEnum
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <code>SLICESTATUS_UNDEFINED = 0;</code>
+     */
+    SLICESTATUS_UNDEFINED(0),
+    /**
+     * <code>SLICESTATUS_PLANNED = 1;</code>
+     */
+    SLICESTATUS_PLANNED(1),
+    /**
+     * <code>SLICESTATUS_INIT = 2;</code>
+     */
+    SLICESTATUS_INIT(2),
+    /**
+     * <code>SLICESTATUS_ACTIVE = 3;</code>
+     */
+    SLICESTATUS_ACTIVE(3),
+    /**
+     * <code>SLICESTATUS_DEINIT = 4;</code>
+     */
+    SLICESTATUS_DEINIT(4),
+    UNRECOGNIZED(-1),
+    ;
+
+    /**
+     * <code>SLICESTATUS_UNDEFINED = 0;</code>
+     */
+    public static final int SLICESTATUS_UNDEFINED_VALUE = 0;
+    /**
+     * <code>SLICESTATUS_PLANNED = 1;</code>
+     */
+    public static final int SLICESTATUS_PLANNED_VALUE = 1;
+    /**
+     * <code>SLICESTATUS_INIT = 2;</code>
+     */
+    public static final int SLICESTATUS_INIT_VALUE = 2;
+    /**
+     * <code>SLICESTATUS_ACTIVE = 3;</code>
+     */
+    public static final int SLICESTATUS_ACTIVE_VALUE = 3;
+    /**
+     * <code>SLICESTATUS_DEINIT = 4;</code>
+     */
+    public static final int SLICESTATUS_DEINIT_VALUE = 4;
+
+
+    public final int getNumber() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     * @deprecated Use {@link #forNumber(int)} instead.
+     */
+    @java.lang.Deprecated
+    public static SliceStatusEnum valueOf(int value) {
+      return forNumber(value);
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     */
+    public static SliceStatusEnum forNumber(int value) {
+      switch (value) {
+        case 0: return SLICESTATUS_UNDEFINED;
+        case 1: return SLICESTATUS_PLANNED;
+        case 2: return SLICESTATUS_INIT;
+        case 3: return SLICESTATUS_ACTIVE;
+        case 4: return SLICESTATUS_DEINIT;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<SliceStatusEnum>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        SliceStatusEnum> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<SliceStatusEnum>() {
+            public SliceStatusEnum findValueByNumber(int number) {
+              return SliceStatusEnum.forNumber(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalStateException(
+            "Can't get the descriptor of an unrecognized enum value.");
+      }
+      return getDescriptor().getValues().get(ordinal());
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return context.ContextOuterClass.getDescriptor().getEnumTypes().get(5);
+    }
+
+    private static final SliceStatusEnum[] VALUES = values();
+
+    public static SliceStatusEnum valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int value;
+
+    private SliceStatusEnum(int value) {
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:context.SliceStatusEnum)
+  }
+
   /**
    * <pre>
    * ----- Configuration -------------------------------------------------------------------------------------------------
@@ -756,7 +891,7 @@ public final class ContextOuterClass {
     }
     public static final com.google.protobuf.Descriptors.EnumDescriptor
         getDescriptor() {
-      return context.ContextOuterClass.getDescriptor().getEnumTypes().get(5);
+      return context.ContextOuterClass.getDescriptor().getEnumTypes().get(6);
     }
 
     private static final ConfigActionEnum[] VALUES = values();
@@ -27653,49 +27788,64 @@ public final class ContextOuterClass {
 
   }
 
-  public interface ConnectionIdOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:context.ConnectionId)
+  public interface SliceIdOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceId)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
-     * @return Whether the connectionUuid field is set.
+     * <code>.context.ContextId context_id = 1;</code>
+     * @return Whether the contextId field is set.
      */
-    boolean hasConnectionUuid();
+    boolean hasContextId();
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
-     * @return The connectionUuid.
+     * <code>.context.ContextId context_id = 1;</code>
+     * @return The contextId.
      */
-    context.ContextOuterClass.Uuid getConnectionUuid();
+    context.ContextOuterClass.ContextId getContextId();
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
+     * <code>.context.ContextId context_id = 1;</code>
      */
-    context.ContextOuterClass.UuidOrBuilder getConnectionUuidOrBuilder();
+    context.ContextOuterClass.ContextIdOrBuilder getContextIdOrBuilder();
+
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     * @return Whether the sliceUuid field is set.
+     */
+    boolean hasSliceUuid();
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     * @return The sliceUuid.
+     */
+    context.ContextOuterClass.Uuid getSliceUuid();
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     */
+    context.ContextOuterClass.UuidOrBuilder getSliceUuidOrBuilder();
   }
   /**
    * <pre>
-   * ----- Connection ----------------------------------------------------------------------------------------------------
+   * ----- Slice ---------------------------------------------------------------------------------------------------------
    * </pre>
    *
-   * Protobuf type {@code context.ConnectionId}
+   * Protobuf type {@code context.SliceId}
    */
-  public static final class ConnectionId extends
+  public static final class SliceId extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:context.ConnectionId)
-      ConnectionIdOrBuilder {
+      // @@protoc_insertion_point(message_implements:context.SliceId)
+      SliceIdOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use ConnectionId.newBuilder() to construct.
-    private ConnectionId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use SliceId.newBuilder() to construct.
+    private SliceId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private ConnectionId() {
+    private SliceId() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new ConnectionId();
+      return new SliceId();
     }
 
     @java.lang.Override
@@ -27703,7 +27853,7 @@ public final class ContextOuterClass {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private ConnectionId(
+    private SliceId(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -27722,14 +27872,27 @@ public final class ContextOuterClass {
               done = true;
               break;
             case 10: {
+              context.ContextOuterClass.ContextId.Builder subBuilder = null;
+              if (contextId_ != null) {
+                subBuilder = contextId_.toBuilder();
+              }
+              contextId_ = input.readMessage(context.ContextOuterClass.ContextId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(contextId_);
+                contextId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
               context.ContextOuterClass.Uuid.Builder subBuilder = null;
-              if (connectionUuid_ != null) {
-                subBuilder = connectionUuid_.toBuilder();
+              if (sliceUuid_ != null) {
+                subBuilder = sliceUuid_.toBuilder();
               }
-              connectionUuid_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              sliceUuid_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(connectionUuid_);
-                connectionUuid_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(sliceUuid_);
+                sliceUuid_ = subBuilder.buildPartial();
               }
 
               break;
@@ -27755,41 +27918,67 @@ public final class ContextOuterClass {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+      return context.ContextOuterClass.internal_static_context_SliceId_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return context.ContextOuterClass.internal_static_context_ConnectionId_fieldAccessorTable
+      return context.ContextOuterClass.internal_static_context_SliceId_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              context.ContextOuterClass.ConnectionId.class, context.ContextOuterClass.ConnectionId.Builder.class);
+              context.ContextOuterClass.SliceId.class, context.ContextOuterClass.SliceId.Builder.class);
     }
 
-    public static final int CONNECTION_UUID_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Uuid connectionUuid_;
+    public static final int CONTEXT_ID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.ContextId contextId_;
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
-     * @return Whether the connectionUuid field is set.
+     * <code>.context.ContextId context_id = 1;</code>
+     * @return Whether the contextId field is set.
      */
     @java.lang.Override
-    public boolean hasConnectionUuid() {
-      return connectionUuid_ != null;
+    public boolean hasContextId() {
+      return contextId_ != null;
     }
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
-     * @return The connectionUuid.
+     * <code>.context.ContextId context_id = 1;</code>
+     * @return The contextId.
      */
     @java.lang.Override
-    public context.ContextOuterClass.Uuid getConnectionUuid() {
-      return connectionUuid_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : connectionUuid_;
+    public context.ContextOuterClass.ContextId getContextId() {
+      return contextId_ == null ? context.ContextOuterClass.ContextId.getDefaultInstance() : contextId_;
     }
     /**
-     * <code>.context.Uuid connection_uuid = 1;</code>
+     * <code>.context.ContextId context_id = 1;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.UuidOrBuilder getConnectionUuidOrBuilder() {
-      return getConnectionUuid();
+    public context.ContextOuterClass.ContextIdOrBuilder getContextIdOrBuilder() {
+      return getContextId();
+    }
+
+    public static final int SLICE_UUID_FIELD_NUMBER = 2;
+    private context.ContextOuterClass.Uuid sliceUuid_;
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     * @return Whether the sliceUuid field is set.
+     */
+    @java.lang.Override
+    public boolean hasSliceUuid() {
+      return sliceUuid_ != null;
+    }
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     * @return The sliceUuid.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Uuid getSliceUuid() {
+      return sliceUuid_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : sliceUuid_;
+    }
+    /**
+     * <code>.context.Uuid slice_uuid = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.UuidOrBuilder getSliceUuidOrBuilder() {
+      return getSliceUuid();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -27806,8 +27995,11 @@ public final class ContextOuterClass {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (connectionUuid_ != null) {
-        output.writeMessage(1, getConnectionUuid());
+      if (contextId_ != null) {
+        output.writeMessage(1, getContextId());
+      }
+      if (sliceUuid_ != null) {
+        output.writeMessage(2, getSliceUuid());
       }
       unknownFields.writeTo(output);
     }
@@ -27818,9 +28010,13 @@ public final class ContextOuterClass {
       if (size != -1) return size;
 
       size = 0;
-      if (connectionUuid_ != null) {
+      if (contextId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getConnectionUuid());
+          .computeMessageSize(1, getContextId());
+      }
+      if (sliceUuid_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getSliceUuid());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -27832,15 +28028,20 @@ public final class ContextOuterClass {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof context.ContextOuterClass.ConnectionId)) {
+      if (!(obj instanceof context.ContextOuterClass.SliceId)) {
         return super.equals(obj);
       }
-      context.ContextOuterClass.ConnectionId other = (context.ContextOuterClass.ConnectionId) obj;
+      context.ContextOuterClass.SliceId other = (context.ContextOuterClass.SliceId) obj;
 
-      if (hasConnectionUuid() != other.hasConnectionUuid()) return false;
-      if (hasConnectionUuid()) {
-        if (!getConnectionUuid()
-            .equals(other.getConnectionUuid())) return false;
+      if (hasContextId() != other.hasContextId()) return false;
+      if (hasContextId()) {
+        if (!getContextId()
+            .equals(other.getContextId())) return false;
+      }
+      if (hasSliceUuid() != other.hasSliceUuid()) return false;
+      if (hasSliceUuid()) {
+        if (!getSliceUuid()
+            .equals(other.getSliceUuid())) return false;
       }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
@@ -27853,78 +28054,82 @@ public final class ContextOuterClass {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasConnectionUuid()) {
-        hash = (37 * hash) + CONNECTION_UUID_FIELD_NUMBER;
-        hash = (53 * hash) + getConnectionUuid().hashCode();
+      if (hasContextId()) {
+        hash = (37 * hash) + CONTEXT_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getContextId().hashCode();
+      }
+      if (hasSliceUuid()) {
+        hash = (37 * hash) + SLICE_UUID_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceUuid().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(byte[] data)
+    public static context.ContextOuterClass.SliceId parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(java.io.InputStream input)
+    public static context.ContextOuterClass.SliceId parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseDelimitedFrom(java.io.InputStream input)
+    public static context.ContextOuterClass.SliceId parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static context.ContextOuterClass.ConnectionId parseDelimitedFrom(
+    public static context.ContextOuterClass.SliceId parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static context.ContextOuterClass.ConnectionId parseFrom(
+    public static context.ContextOuterClass.SliceId parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -27937,7 +28142,7 @@ public final class ContextOuterClass {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(context.ContextOuterClass.ConnectionId prototype) {
+    public static Builder newBuilder(context.ContextOuterClass.SliceId prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -27954,29 +28159,29 @@ public final class ContextOuterClass {
     }
     /**
      * <pre>
-     * ----- Connection ----------------------------------------------------------------------------------------------------
+     * ----- Slice ---------------------------------------------------------------------------------------------------------
      * </pre>
      *
-     * Protobuf type {@code context.ConnectionId}
+     * Protobuf type {@code context.SliceId}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:context.ConnectionId)
-        context.ContextOuterClass.ConnectionIdOrBuilder {
+        // @@protoc_insertion_point(builder_implements:context.SliceId)
+        context.ContextOuterClass.SliceIdOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+        return context.ContextOuterClass.internal_static_context_SliceId_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return context.ContextOuterClass.internal_static_context_ConnectionId_fieldAccessorTable
+        return context.ContextOuterClass.internal_static_context_SliceId_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                context.ContextOuterClass.ConnectionId.class, context.ContextOuterClass.ConnectionId.Builder.class);
+                context.ContextOuterClass.SliceId.class, context.ContextOuterClass.SliceId.Builder.class);
       }
 
-      // Construct using context.ContextOuterClass.ConnectionId.newBuilder()
+      // Construct using context.ContextOuterClass.SliceId.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -27994,11 +28199,17 @@ public final class ContextOuterClass {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (connectionUuidBuilder_ == null) {
-          connectionUuid_ = null;
+        if (contextIdBuilder_ == null) {
+          contextId_ = null;
         } else {
-          connectionUuid_ = null;
-          connectionUuidBuilder_ = null;
+          contextId_ = null;
+          contextIdBuilder_ = null;
+        }
+        if (sliceUuidBuilder_ == null) {
+          sliceUuid_ = null;
+        } else {
+          sliceUuid_ = null;
+          sliceUuidBuilder_ = null;
         }
         return this;
       }
@@ -28006,17 +28217,17 @@ public final class ContextOuterClass {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+        return context.ContextOuterClass.internal_static_context_SliceId_descriptor;
       }
 
       @java.lang.Override
-      public context.ContextOuterClass.ConnectionId getDefaultInstanceForType() {
-        return context.ContextOuterClass.ConnectionId.getDefaultInstance();
+      public context.ContextOuterClass.SliceId getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceId.getDefaultInstance();
       }
 
       @java.lang.Override
-      public context.ContextOuterClass.ConnectionId build() {
-        context.ContextOuterClass.ConnectionId result = buildPartial();
+      public context.ContextOuterClass.SliceId build() {
+        context.ContextOuterClass.SliceId result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -28024,12 +28235,6018 @@ public final class ContextOuterClass {
       }
 
       @java.lang.Override
-      public context.ContextOuterClass.ConnectionId buildPartial() {
-        context.ContextOuterClass.ConnectionId result = new context.ContextOuterClass.ConnectionId(this);
-        if (connectionUuidBuilder_ == null) {
-          result.connectionUuid_ = connectionUuid_;
+      public context.ContextOuterClass.SliceId buildPartial() {
+        context.ContextOuterClass.SliceId result = new context.ContextOuterClass.SliceId(this);
+        if (contextIdBuilder_ == null) {
+          result.contextId_ = contextId_;
         } else {
-          result.connectionUuid_ = connectionUuidBuilder_.build();
+          result.contextId_ = contextIdBuilder_.build();
+        }
+        if (sliceUuidBuilder_ == null) {
+          result.sliceUuid_ = sliceUuid_;
+        } else {
+          result.sliceUuid_ = sliceUuidBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceId) {
+          return mergeFrom((context.ContextOuterClass.SliceId)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceId other) {
+        if (other == context.ContextOuterClass.SliceId.getDefaultInstance()) return this;
+        if (other.hasContextId()) {
+          mergeContextId(other.getContextId());
+        }
+        if (other.hasSliceUuid()) {
+          mergeSliceUuid(other.getSliceUuid());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceId parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceId) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private context.ContextOuterClass.ContextId contextId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ContextId, context.ContextOuterClass.ContextId.Builder, context.ContextOuterClass.ContextIdOrBuilder> contextIdBuilder_;
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       * @return Whether the contextId field is set.
+       */
+      public boolean hasContextId() {
+        return contextIdBuilder_ != null || contextId_ != null;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       * @return The contextId.
+       */
+      public context.ContextOuterClass.ContextId getContextId() {
+        if (contextIdBuilder_ == null) {
+          return contextId_ == null ? context.ContextOuterClass.ContextId.getDefaultInstance() : contextId_;
+        } else {
+          return contextIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public Builder setContextId(context.ContextOuterClass.ContextId value) {
+        if (contextIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          contextId_ = value;
+          onChanged();
+        } else {
+          contextIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public Builder setContextId(
+          context.ContextOuterClass.ContextId.Builder builderForValue) {
+        if (contextIdBuilder_ == null) {
+          contextId_ = builderForValue.build();
+          onChanged();
+        } else {
+          contextIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public Builder mergeContextId(context.ContextOuterClass.ContextId value) {
+        if (contextIdBuilder_ == null) {
+          if (contextId_ != null) {
+            contextId_ =
+              context.ContextOuterClass.ContextId.newBuilder(contextId_).mergeFrom(value).buildPartial();
+          } else {
+            contextId_ = value;
+          }
+          onChanged();
+        } else {
+          contextIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public Builder clearContextId() {
+        if (contextIdBuilder_ == null) {
+          contextId_ = null;
+          onChanged();
+        } else {
+          contextId_ = null;
+          contextIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public context.ContextOuterClass.ContextId.Builder getContextIdBuilder() {
+        
+        onChanged();
+        return getContextIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      public context.ContextOuterClass.ContextIdOrBuilder getContextIdOrBuilder() {
+        if (contextIdBuilder_ != null) {
+          return contextIdBuilder_.getMessageOrBuilder();
+        } else {
+          return contextId_ == null ?
+              context.ContextOuterClass.ContextId.getDefaultInstance() : contextId_;
+        }
+      }
+      /**
+       * <code>.context.ContextId context_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ContextId, context.ContextOuterClass.ContextId.Builder, context.ContextOuterClass.ContextIdOrBuilder> 
+          getContextIdFieldBuilder() {
+        if (contextIdBuilder_ == null) {
+          contextIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.ContextId, context.ContextOuterClass.ContextId.Builder, context.ContextOuterClass.ContextIdOrBuilder>(
+                  getContextId(),
+                  getParentForChildren(),
+                  isClean());
+          contextId_ = null;
+        }
+        return contextIdBuilder_;
+      }
+
+      private context.ContextOuterClass.Uuid sliceUuid_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> sliceUuidBuilder_;
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       * @return Whether the sliceUuid field is set.
+       */
+      public boolean hasSliceUuid() {
+        return sliceUuidBuilder_ != null || sliceUuid_ != null;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       * @return The sliceUuid.
+       */
+      public context.ContextOuterClass.Uuid getSliceUuid() {
+        if (sliceUuidBuilder_ == null) {
+          return sliceUuid_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : sliceUuid_;
+        } else {
+          return sliceUuidBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public Builder setSliceUuid(context.ContextOuterClass.Uuid value) {
+        if (sliceUuidBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          sliceUuid_ = value;
+          onChanged();
+        } else {
+          sliceUuidBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public Builder setSliceUuid(
+          context.ContextOuterClass.Uuid.Builder builderForValue) {
+        if (sliceUuidBuilder_ == null) {
+          sliceUuid_ = builderForValue.build();
+          onChanged();
+        } else {
+          sliceUuidBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public Builder mergeSliceUuid(context.ContextOuterClass.Uuid value) {
+        if (sliceUuidBuilder_ == null) {
+          if (sliceUuid_ != null) {
+            sliceUuid_ =
+              context.ContextOuterClass.Uuid.newBuilder(sliceUuid_).mergeFrom(value).buildPartial();
+          } else {
+            sliceUuid_ = value;
+          }
+          onChanged();
+        } else {
+          sliceUuidBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public Builder clearSliceUuid() {
+        if (sliceUuidBuilder_ == null) {
+          sliceUuid_ = null;
+          onChanged();
+        } else {
+          sliceUuid_ = null;
+          sliceUuidBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public context.ContextOuterClass.Uuid.Builder getSliceUuidBuilder() {
+        
+        onChanged();
+        return getSliceUuidFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      public context.ContextOuterClass.UuidOrBuilder getSliceUuidOrBuilder() {
+        if (sliceUuidBuilder_ != null) {
+          return sliceUuidBuilder_.getMessageOrBuilder();
+        } else {
+          return sliceUuid_ == null ?
+              context.ContextOuterClass.Uuid.getDefaultInstance() : sliceUuid_;
+        }
+      }
+      /**
+       * <code>.context.Uuid slice_uuid = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
+          getSliceUuidFieldBuilder() {
+        if (sliceUuidBuilder_ == null) {
+          sliceUuidBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
+                  getSliceUuid(),
+                  getParentForChildren(),
+                  isClean());
+          sliceUuid_ = null;
+        }
+        return sliceUuidBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceId)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceId)
+    private static final context.ContextOuterClass.SliceId DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceId();
+    }
+
+    public static context.ContextOuterClass.SliceId getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceId>
+        PARSER = new com.google.protobuf.AbstractParser<SliceId>() {
+      @java.lang.Override
+      public SliceId parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceId(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceId> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceId> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.Slice)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     * @return Whether the sliceId field is set.
+     */
+    boolean hasSliceId();
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     * @return The sliceId.
+     */
+    context.ContextOuterClass.SliceId getSliceId();
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     */
+    context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
+
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    java.util.List<context.ContextOuterClass.EndPointId> 
+        getSliceEndpointIdsList();
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    context.ContextOuterClass.EndPointId getSliceEndpointIds(int index);
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    int getSliceEndpointIdsCount();
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.EndPointIdOrBuilder> 
+        getSliceEndpointIdsOrBuilderList();
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    context.ContextOuterClass.EndPointIdOrBuilder getSliceEndpointIdsOrBuilder(
+        int index);
+
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    java.util.List<context.ContextOuterClass.Constraint> 
+        getSliceConstraintsList();
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    context.ContextOuterClass.Constraint getSliceConstraints(int index);
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    int getSliceConstraintsCount();
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.ConstraintOrBuilder> 
+        getSliceConstraintsOrBuilderList();
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    context.ContextOuterClass.ConstraintOrBuilder getSliceConstraintsOrBuilder(
+        int index);
+
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    java.util.List<context.ContextOuterClass.ServiceId> 
+        getSliceServiceIdsList();
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    context.ContextOuterClass.ServiceId getSliceServiceIds(int index);
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    int getSliceServiceIdsCount();
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.ServiceIdOrBuilder> 
+        getSliceServiceIdsOrBuilderList();
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    context.ContextOuterClass.ServiceIdOrBuilder getSliceServiceIdsOrBuilder(
+        int index);
+
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    java.util.List<context.ContextOuterClass.SliceId> 
+        getSliceSubsliceIdsList();
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    context.ContextOuterClass.SliceId getSliceSubsliceIds(int index);
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    int getSliceSubsliceIdsCount();
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+        getSliceSubsliceIdsOrBuilderList();
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    context.ContextOuterClass.SliceIdOrBuilder getSliceSubsliceIdsOrBuilder(
+        int index);
+
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     * @return Whether the sliceStatus field is set.
+     */
+    boolean hasSliceStatus();
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     * @return The sliceStatus.
+     */
+    context.ContextOuterClass.SliceStatus getSliceStatus();
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     */
+    context.ContextOuterClass.SliceStatusOrBuilder getSliceStatusOrBuilder();
+  }
+  /**
+   * Protobuf type {@code context.Slice}
+   */
+  public static final class Slice extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.Slice)
+      SliceOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use Slice.newBuilder() to construct.
+    private Slice(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private Slice() {
+      sliceEndpointIds_ = java.util.Collections.emptyList();
+      sliceConstraints_ = java.util.Collections.emptyList();
+      sliceServiceIds_ = java.util.Collections.emptyList();
+      sliceSubsliceIds_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new Slice();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Slice(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              context.ContextOuterClass.SliceId.Builder subBuilder = null;
+              if (sliceId_ != null) {
+                subBuilder = sliceId_.toBuilder();
+              }
+              sliceId_ = input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(sliceId_);
+                sliceId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                sliceEndpointIds_ = new java.util.ArrayList<context.ContextOuterClass.EndPointId>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              sliceEndpointIds_.add(
+                  input.readMessage(context.ContextOuterClass.EndPointId.parser(), extensionRegistry));
+              break;
+            }
+            case 26: {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+                sliceConstraints_ = new java.util.ArrayList<context.ContextOuterClass.Constraint>();
+                mutable_bitField0_ |= 0x00000002;
+              }
+              sliceConstraints_.add(
+                  input.readMessage(context.ContextOuterClass.Constraint.parser(), extensionRegistry));
+              break;
+            }
+            case 34: {
+              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
+                sliceServiceIds_ = new java.util.ArrayList<context.ContextOuterClass.ServiceId>();
+                mutable_bitField0_ |= 0x00000004;
+              }
+              sliceServiceIds_.add(
+                  input.readMessage(context.ContextOuterClass.ServiceId.parser(), extensionRegistry));
+              break;
+            }
+            case 42: {
+              if (!((mutable_bitField0_ & 0x00000008) != 0)) {
+                sliceSubsliceIds_ = new java.util.ArrayList<context.ContextOuterClass.SliceId>();
+                mutable_bitField0_ |= 0x00000008;
+              }
+              sliceSubsliceIds_.add(
+                  input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry));
+              break;
+            }
+            case 50: {
+              context.ContextOuterClass.SliceStatus.Builder subBuilder = null;
+              if (sliceStatus_ != null) {
+                subBuilder = sliceStatus_.toBuilder();
+              }
+              sliceStatus_ = input.readMessage(context.ContextOuterClass.SliceStatus.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(sliceStatus_);
+                sliceStatus_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          sliceEndpointIds_ = java.util.Collections.unmodifiableList(sliceEndpointIds_);
+        }
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
+          sliceConstraints_ = java.util.Collections.unmodifiableList(sliceConstraints_);
+        }
+        if (((mutable_bitField0_ & 0x00000004) != 0)) {
+          sliceServiceIds_ = java.util.Collections.unmodifiableList(sliceServiceIds_);
+        }
+        if (((mutable_bitField0_ & 0x00000008) != 0)) {
+          sliceSubsliceIds_ = java.util.Collections.unmodifiableList(sliceSubsliceIds_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_Slice_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_Slice_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.Slice.class, context.ContextOuterClass.Slice.Builder.class);
+    }
+
+    public static final int SLICE_ID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.SliceId sliceId_;
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     * @return Whether the sliceId field is set.
+     */
+    @java.lang.Override
+    public boolean hasSliceId() {
+      return sliceId_ != null;
+    }
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     * @return The sliceId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getSliceId() {
+      return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+    }
+    /**
+     * <code>.context.SliceId slice_id = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
+      return getSliceId();
+    }
+
+    public static final int SLICE_ENDPOINT_IDS_FIELD_NUMBER = 2;
+    private java.util.List<context.ContextOuterClass.EndPointId> sliceEndpointIds_;
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.EndPointId> getSliceEndpointIdsList() {
+      return sliceEndpointIds_;
+    }
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.EndPointIdOrBuilder> 
+        getSliceEndpointIdsOrBuilderList() {
+      return sliceEndpointIds_;
+    }
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public int getSliceEndpointIdsCount() {
+      return sliceEndpointIds_.size();
+    }
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.EndPointId getSliceEndpointIds(int index) {
+      return sliceEndpointIds_.get(index);
+    }
+    /**
+     * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.EndPointIdOrBuilder getSliceEndpointIdsOrBuilder(
+        int index) {
+      return sliceEndpointIds_.get(index);
+    }
+
+    public static final int SLICE_CONSTRAINTS_FIELD_NUMBER = 3;
+    private java.util.List<context.ContextOuterClass.Constraint> sliceConstraints_;
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.Constraint> getSliceConstraintsList() {
+      return sliceConstraints_;
+    }
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.ConstraintOrBuilder> 
+        getSliceConstraintsOrBuilderList() {
+      return sliceConstraints_;
+    }
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public int getSliceConstraintsCount() {
+      return sliceConstraints_.size();
+    }
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Constraint getSliceConstraints(int index) {
+      return sliceConstraints_.get(index);
+    }
+    /**
+     * <code>repeated .context.Constraint slice_constraints = 3;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ConstraintOrBuilder getSliceConstraintsOrBuilder(
+        int index) {
+      return sliceConstraints_.get(index);
+    }
+
+    public static final int SLICE_SERVICE_IDS_FIELD_NUMBER = 4;
+    private java.util.List<context.ContextOuterClass.ServiceId> sliceServiceIds_;
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.ServiceId> getSliceServiceIdsList() {
+      return sliceServiceIds_;
+    }
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.ServiceIdOrBuilder> 
+        getSliceServiceIdsOrBuilderList() {
+      return sliceServiceIds_;
+    }
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public int getSliceServiceIdsCount() {
+      return sliceServiceIds_.size();
+    }
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ServiceId getSliceServiceIds(int index) {
+      return sliceServiceIds_.get(index);
+    }
+    /**
+     * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ServiceIdOrBuilder getSliceServiceIdsOrBuilder(
+        int index) {
+      return sliceServiceIds_.get(index);
+    }
+
+    public static final int SLICE_SUBSLICE_IDS_FIELD_NUMBER = 5;
+    private java.util.List<context.ContextOuterClass.SliceId> sliceSubsliceIds_;
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.SliceId> getSliceSubsliceIdsList() {
+      return sliceSubsliceIds_;
+    }
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+        getSliceSubsliceIdsOrBuilderList() {
+      return sliceSubsliceIds_;
+    }
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public int getSliceSubsliceIdsCount() {
+      return sliceSubsliceIds_.size();
+    }
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getSliceSubsliceIds(int index) {
+      return sliceSubsliceIds_.get(index);
+    }
+    /**
+     * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdOrBuilder getSliceSubsliceIdsOrBuilder(
+        int index) {
+      return sliceSubsliceIds_.get(index);
+    }
+
+    public static final int SLICE_STATUS_FIELD_NUMBER = 6;
+    private context.ContextOuterClass.SliceStatus sliceStatus_;
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     * @return Whether the sliceStatus field is set.
+     */
+    @java.lang.Override
+    public boolean hasSliceStatus() {
+      return sliceStatus_ != null;
+    }
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     * @return The sliceStatus.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceStatus getSliceStatus() {
+      return sliceStatus_ == null ? context.ContextOuterClass.SliceStatus.getDefaultInstance() : sliceStatus_;
+    }
+    /**
+     * <code>.context.SliceStatus slice_status = 6;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceStatusOrBuilder getSliceStatusOrBuilder() {
+      return getSliceStatus();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (sliceId_ != null) {
+        output.writeMessage(1, getSliceId());
+      }
+      for (int i = 0; i < sliceEndpointIds_.size(); i++) {
+        output.writeMessage(2, sliceEndpointIds_.get(i));
+      }
+      for (int i = 0; i < sliceConstraints_.size(); i++) {
+        output.writeMessage(3, sliceConstraints_.get(i));
+      }
+      for (int i = 0; i < sliceServiceIds_.size(); i++) {
+        output.writeMessage(4, sliceServiceIds_.get(i));
+      }
+      for (int i = 0; i < sliceSubsliceIds_.size(); i++) {
+        output.writeMessage(5, sliceSubsliceIds_.get(i));
+      }
+      if (sliceStatus_ != null) {
+        output.writeMessage(6, getSliceStatus());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (sliceId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getSliceId());
+      }
+      for (int i = 0; i < sliceEndpointIds_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, sliceEndpointIds_.get(i));
+      }
+      for (int i = 0; i < sliceConstraints_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, sliceConstraints_.get(i));
+      }
+      for (int i = 0; i < sliceServiceIds_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, sliceServiceIds_.get(i));
+      }
+      for (int i = 0; i < sliceSubsliceIds_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, sliceSubsliceIds_.get(i));
+      }
+      if (sliceStatus_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, getSliceStatus());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.Slice)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.Slice other = (context.ContextOuterClass.Slice) obj;
+
+      if (hasSliceId() != other.hasSliceId()) return false;
+      if (hasSliceId()) {
+        if (!getSliceId()
+            .equals(other.getSliceId())) return false;
+      }
+      if (!getSliceEndpointIdsList()
+          .equals(other.getSliceEndpointIdsList())) return false;
+      if (!getSliceConstraintsList()
+          .equals(other.getSliceConstraintsList())) return false;
+      if (!getSliceServiceIdsList()
+          .equals(other.getSliceServiceIdsList())) return false;
+      if (!getSliceSubsliceIdsList()
+          .equals(other.getSliceSubsliceIdsList())) return false;
+      if (hasSliceStatus() != other.hasSliceStatus()) return false;
+      if (hasSliceStatus()) {
+        if (!getSliceStatus()
+            .equals(other.getSliceStatus())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasSliceId()) {
+        hash = (37 * hash) + SLICE_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceId().hashCode();
+      }
+      if (getSliceEndpointIdsCount() > 0) {
+        hash = (37 * hash) + SLICE_ENDPOINT_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceEndpointIdsList().hashCode();
+      }
+      if (getSliceConstraintsCount() > 0) {
+        hash = (37 * hash) + SLICE_CONSTRAINTS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceConstraintsList().hashCode();
+      }
+      if (getSliceServiceIdsCount() > 0) {
+        hash = (37 * hash) + SLICE_SERVICE_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceServiceIdsList().hashCode();
+      }
+      if (getSliceSubsliceIdsCount() > 0) {
+        hash = (37 * hash) + SLICE_SUBSLICE_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceSubsliceIdsList().hashCode();
+      }
+      if (hasSliceStatus()) {
+        hash = (37 * hash) + SLICE_STATUS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceStatus().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.Slice parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.Slice parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.Slice parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.Slice prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.Slice}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.Slice)
+        context.ContextOuterClass.SliceOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_Slice_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_Slice_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.Slice.class, context.ContextOuterClass.Slice.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.Slice.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getSliceEndpointIdsFieldBuilder();
+          getSliceConstraintsFieldBuilder();
+          getSliceServiceIdsFieldBuilder();
+          getSliceSubsliceIdsFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+        if (sliceEndpointIdsBuilder_ == null) {
+          sliceEndpointIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          sliceEndpointIdsBuilder_.clear();
+        }
+        if (sliceConstraintsBuilder_ == null) {
+          sliceConstraints_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+        } else {
+          sliceConstraintsBuilder_.clear();
+        }
+        if (sliceServiceIdsBuilder_ == null) {
+          sliceServiceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000004);
+        } else {
+          sliceServiceIdsBuilder_.clear();
+        }
+        if (sliceSubsliceIdsBuilder_ == null) {
+          sliceSubsliceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+        } else {
+          sliceSubsliceIdsBuilder_.clear();
+        }
+        if (sliceStatusBuilder_ == null) {
+          sliceStatus_ = null;
+        } else {
+          sliceStatus_ = null;
+          sliceStatusBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_Slice_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.Slice getDefaultInstanceForType() {
+        return context.ContextOuterClass.Slice.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.Slice build() {
+        context.ContextOuterClass.Slice result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.Slice buildPartial() {
+        context.ContextOuterClass.Slice result = new context.ContextOuterClass.Slice(this);
+        int from_bitField0_ = bitField0_;
+        if (sliceIdBuilder_ == null) {
+          result.sliceId_ = sliceId_;
+        } else {
+          result.sliceId_ = sliceIdBuilder_.build();
+        }
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            sliceEndpointIds_ = java.util.Collections.unmodifiableList(sliceEndpointIds_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.sliceEndpointIds_ = sliceEndpointIds_;
+        } else {
+          result.sliceEndpointIds_ = sliceEndpointIdsBuilder_.build();
+        }
+        if (sliceConstraintsBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) != 0)) {
+            sliceConstraints_ = java.util.Collections.unmodifiableList(sliceConstraints_);
+            bitField0_ = (bitField0_ & ~0x00000002);
+          }
+          result.sliceConstraints_ = sliceConstraints_;
+        } else {
+          result.sliceConstraints_ = sliceConstraintsBuilder_.build();
+        }
+        if (sliceServiceIdsBuilder_ == null) {
+          if (((bitField0_ & 0x00000004) != 0)) {
+            sliceServiceIds_ = java.util.Collections.unmodifiableList(sliceServiceIds_);
+            bitField0_ = (bitField0_ & ~0x00000004);
+          }
+          result.sliceServiceIds_ = sliceServiceIds_;
+        } else {
+          result.sliceServiceIds_ = sliceServiceIdsBuilder_.build();
+        }
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (((bitField0_ & 0x00000008) != 0)) {
+            sliceSubsliceIds_ = java.util.Collections.unmodifiableList(sliceSubsliceIds_);
+            bitField0_ = (bitField0_ & ~0x00000008);
+          }
+          result.sliceSubsliceIds_ = sliceSubsliceIds_;
+        } else {
+          result.sliceSubsliceIds_ = sliceSubsliceIdsBuilder_.build();
+        }
+        if (sliceStatusBuilder_ == null) {
+          result.sliceStatus_ = sliceStatus_;
+        } else {
+          result.sliceStatus_ = sliceStatusBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.Slice) {
+          return mergeFrom((context.ContextOuterClass.Slice)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.Slice other) {
+        if (other == context.ContextOuterClass.Slice.getDefaultInstance()) return this;
+        if (other.hasSliceId()) {
+          mergeSliceId(other.getSliceId());
+        }
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (!other.sliceEndpointIds_.isEmpty()) {
+            if (sliceEndpointIds_.isEmpty()) {
+              sliceEndpointIds_ = other.sliceEndpointIds_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureSliceEndpointIdsIsMutable();
+              sliceEndpointIds_.addAll(other.sliceEndpointIds_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceEndpointIds_.isEmpty()) {
+            if (sliceEndpointIdsBuilder_.isEmpty()) {
+              sliceEndpointIdsBuilder_.dispose();
+              sliceEndpointIdsBuilder_ = null;
+              sliceEndpointIds_ = other.sliceEndpointIds_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              sliceEndpointIdsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceEndpointIdsFieldBuilder() : null;
+            } else {
+              sliceEndpointIdsBuilder_.addAllMessages(other.sliceEndpointIds_);
+            }
+          }
+        }
+        if (sliceConstraintsBuilder_ == null) {
+          if (!other.sliceConstraints_.isEmpty()) {
+            if (sliceConstraints_.isEmpty()) {
+              sliceConstraints_ = other.sliceConstraints_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+            } else {
+              ensureSliceConstraintsIsMutable();
+              sliceConstraints_.addAll(other.sliceConstraints_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceConstraints_.isEmpty()) {
+            if (sliceConstraintsBuilder_.isEmpty()) {
+              sliceConstraintsBuilder_.dispose();
+              sliceConstraintsBuilder_ = null;
+              sliceConstraints_ = other.sliceConstraints_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+              sliceConstraintsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceConstraintsFieldBuilder() : null;
+            } else {
+              sliceConstraintsBuilder_.addAllMessages(other.sliceConstraints_);
+            }
+          }
+        }
+        if (sliceServiceIdsBuilder_ == null) {
+          if (!other.sliceServiceIds_.isEmpty()) {
+            if (sliceServiceIds_.isEmpty()) {
+              sliceServiceIds_ = other.sliceServiceIds_;
+              bitField0_ = (bitField0_ & ~0x00000004);
+            } else {
+              ensureSliceServiceIdsIsMutable();
+              sliceServiceIds_.addAll(other.sliceServiceIds_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceServiceIds_.isEmpty()) {
+            if (sliceServiceIdsBuilder_.isEmpty()) {
+              sliceServiceIdsBuilder_.dispose();
+              sliceServiceIdsBuilder_ = null;
+              sliceServiceIds_ = other.sliceServiceIds_;
+              bitField0_ = (bitField0_ & ~0x00000004);
+              sliceServiceIdsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceServiceIdsFieldBuilder() : null;
+            } else {
+              sliceServiceIdsBuilder_.addAllMessages(other.sliceServiceIds_);
+            }
+          }
+        }
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (!other.sliceSubsliceIds_.isEmpty()) {
+            if (sliceSubsliceIds_.isEmpty()) {
+              sliceSubsliceIds_ = other.sliceSubsliceIds_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+            } else {
+              ensureSliceSubsliceIdsIsMutable();
+              sliceSubsliceIds_.addAll(other.sliceSubsliceIds_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceSubsliceIds_.isEmpty()) {
+            if (sliceSubsliceIdsBuilder_.isEmpty()) {
+              sliceSubsliceIdsBuilder_.dispose();
+              sliceSubsliceIdsBuilder_ = null;
+              sliceSubsliceIds_ = other.sliceSubsliceIds_;
+              bitField0_ = (bitField0_ & ~0x00000008);
+              sliceSubsliceIdsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceSubsliceIdsFieldBuilder() : null;
+            } else {
+              sliceSubsliceIdsBuilder_.addAllMessages(other.sliceSubsliceIds_);
+            }
+          }
+        }
+        if (other.hasSliceStatus()) {
+          mergeSliceStatus(other.getSliceStatus());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.Slice parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.Slice) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private context.ContextOuterClass.SliceId sliceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceIdBuilder_;
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       * @return Whether the sliceId field is set.
+       */
+      public boolean hasSliceId() {
+        return sliceIdBuilder_ != null || sliceId_ != null;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       * @return The sliceId.
+       */
+      public context.ContextOuterClass.SliceId getSliceId() {
+        if (sliceIdBuilder_ == null) {
+          return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+        } else {
+          return sliceIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public Builder setSliceId(context.ContextOuterClass.SliceId value) {
+        if (sliceIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          sliceId_ = value;
+          onChanged();
+        } else {
+          sliceIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public Builder setSliceId(
+          context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = builderForValue.build();
+          onChanged();
+        } else {
+          sliceIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public Builder mergeSliceId(context.ContextOuterClass.SliceId value) {
+        if (sliceIdBuilder_ == null) {
+          if (sliceId_ != null) {
+            sliceId_ =
+              context.ContextOuterClass.SliceId.newBuilder(sliceId_).mergeFrom(value).buildPartial();
+          } else {
+            sliceId_ = value;
+          }
+          onChanged();
+        } else {
+          sliceIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public Builder clearSliceId() {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+          onChanged();
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
+        
+        onChanged();
+        return getSliceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
+        if (sliceIdBuilder_ != null) {
+          return sliceIdBuilder_.getMessageOrBuilder();
+        } else {
+          return sliceId_ == null ?
+              context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+        }
+      }
+      /**
+       * <code>.context.SliceId slice_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> 
+          getSliceIdFieldBuilder() {
+        if (sliceIdBuilder_ == null) {
+          sliceIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder>(
+                  getSliceId(),
+                  getParentForChildren(),
+                  isClean());
+          sliceId_ = null;
+        }
+        return sliceIdBuilder_;
+      }
+
+      private java.util.List<context.ContextOuterClass.EndPointId> sliceEndpointIds_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceEndpointIdsIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          sliceEndpointIds_ = new java.util.ArrayList<context.ContextOuterClass.EndPointId>(sliceEndpointIds_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder> sliceEndpointIdsBuilder_;
+
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public java.util.List<context.ContextOuterClass.EndPointId> getSliceEndpointIdsList() {
+        if (sliceEndpointIdsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceEndpointIds_);
+        } else {
+          return sliceEndpointIdsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public int getSliceEndpointIdsCount() {
+        if (sliceEndpointIdsBuilder_ == null) {
+          return sliceEndpointIds_.size();
+        } else {
+          return sliceEndpointIdsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointId getSliceEndpointIds(int index) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          return sliceEndpointIds_.get(index);
+        } else {
+          return sliceEndpointIdsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder setSliceEndpointIds(
+          int index, context.ContextOuterClass.EndPointId value) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.set(index, value);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder setSliceEndpointIds(
+          int index, context.ContextOuterClass.EndPointId.Builder builderForValue) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addSliceEndpointIds(context.ContextOuterClass.EndPointId value) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.add(value);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addSliceEndpointIds(
+          int index, context.ContextOuterClass.EndPointId value) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.add(index, value);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addSliceEndpointIds(
+          context.ContextOuterClass.EndPointId.Builder builderForValue) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addSliceEndpointIds(
+          int index, context.ContextOuterClass.EndPointId.Builder builderForValue) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder addAllSliceEndpointIds(
+          java.lang.Iterable<? extends context.ContextOuterClass.EndPointId> values) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceEndpointIds_);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder clearSliceEndpointIds() {
+        if (sliceEndpointIdsBuilder_ == null) {
+          sliceEndpointIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public Builder removeSliceEndpointIds(int index) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          ensureSliceEndpointIdsIsMutable();
+          sliceEndpointIds_.remove(index);
+          onChanged();
+        } else {
+          sliceEndpointIdsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointId.Builder getSliceEndpointIdsBuilder(
+          int index) {
+        return getSliceEndpointIdsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointIdOrBuilder getSliceEndpointIdsOrBuilder(
+          int index) {
+        if (sliceEndpointIdsBuilder_ == null) {
+          return sliceEndpointIds_.get(index);  } else {
+          return sliceEndpointIdsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.EndPointIdOrBuilder> 
+           getSliceEndpointIdsOrBuilderList() {
+        if (sliceEndpointIdsBuilder_ != null) {
+          return sliceEndpointIdsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceEndpointIds_);
+        }
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointId.Builder addSliceEndpointIdsBuilder() {
+        return getSliceEndpointIdsFieldBuilder().addBuilder(
+            context.ContextOuterClass.EndPointId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public context.ContextOuterClass.EndPointId.Builder addSliceEndpointIdsBuilder(
+          int index) {
+        return getSliceEndpointIdsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.EndPointId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.EndPointId slice_endpoint_ids = 2;</code>
+       */
+      public java.util.List<context.ContextOuterClass.EndPointId.Builder> 
+           getSliceEndpointIdsBuilderList() {
+        return getSliceEndpointIdsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder> 
+          getSliceEndpointIdsFieldBuilder() {
+        if (sliceEndpointIdsBuilder_ == null) {
+          sliceEndpointIdsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder>(
+                  sliceEndpointIds_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceEndpointIds_ = null;
+        }
+        return sliceEndpointIdsBuilder_;
+      }
+
+      private java.util.List<context.ContextOuterClass.Constraint> sliceConstraints_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceConstraintsIsMutable() {
+        if (!((bitField0_ & 0x00000002) != 0)) {
+          sliceConstraints_ = new java.util.ArrayList<context.ContextOuterClass.Constraint>(sliceConstraints_);
+          bitField0_ |= 0x00000002;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.Constraint, context.ContextOuterClass.Constraint.Builder, context.ContextOuterClass.ConstraintOrBuilder> sliceConstraintsBuilder_;
+
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public java.util.List<context.ContextOuterClass.Constraint> getSliceConstraintsList() {
+        if (sliceConstraintsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceConstraints_);
+        } else {
+          return sliceConstraintsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public int getSliceConstraintsCount() {
+        if (sliceConstraintsBuilder_ == null) {
+          return sliceConstraints_.size();
+        } else {
+          return sliceConstraintsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.Constraint getSliceConstraints(int index) {
+        if (sliceConstraintsBuilder_ == null) {
+          return sliceConstraints_.get(index);
+        } else {
+          return sliceConstraintsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder setSliceConstraints(
+          int index, context.ContextOuterClass.Constraint value) {
+        if (sliceConstraintsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.set(index, value);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder setSliceConstraints(
+          int index, context.ContextOuterClass.Constraint.Builder builderForValue) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addSliceConstraints(context.ContextOuterClass.Constraint value) {
+        if (sliceConstraintsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.add(value);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addSliceConstraints(
+          int index, context.ContextOuterClass.Constraint value) {
+        if (sliceConstraintsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.add(index, value);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addSliceConstraints(
+          context.ContextOuterClass.Constraint.Builder builderForValue) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addSliceConstraints(
+          int index, context.ContextOuterClass.Constraint.Builder builderForValue) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder addAllSliceConstraints(
+          java.lang.Iterable<? extends context.ContextOuterClass.Constraint> values) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceConstraints_);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder clearSliceConstraints() {
+        if (sliceConstraintsBuilder_ == null) {
+          sliceConstraints_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public Builder removeSliceConstraints(int index) {
+        if (sliceConstraintsBuilder_ == null) {
+          ensureSliceConstraintsIsMutable();
+          sliceConstraints_.remove(index);
+          onChanged();
+        } else {
+          sliceConstraintsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.Constraint.Builder getSliceConstraintsBuilder(
+          int index) {
+        return getSliceConstraintsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.ConstraintOrBuilder getSliceConstraintsOrBuilder(
+          int index) {
+        if (sliceConstraintsBuilder_ == null) {
+          return sliceConstraints_.get(index);  } else {
+          return sliceConstraintsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.ConstraintOrBuilder> 
+           getSliceConstraintsOrBuilderList() {
+        if (sliceConstraintsBuilder_ != null) {
+          return sliceConstraintsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceConstraints_);
+        }
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.Constraint.Builder addSliceConstraintsBuilder() {
+        return getSliceConstraintsFieldBuilder().addBuilder(
+            context.ContextOuterClass.Constraint.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public context.ContextOuterClass.Constraint.Builder addSliceConstraintsBuilder(
+          int index) {
+        return getSliceConstraintsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.Constraint.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.Constraint slice_constraints = 3;</code>
+       */
+      public java.util.List<context.ContextOuterClass.Constraint.Builder> 
+           getSliceConstraintsBuilderList() {
+        return getSliceConstraintsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.Constraint, context.ContextOuterClass.Constraint.Builder, context.ContextOuterClass.ConstraintOrBuilder> 
+          getSliceConstraintsFieldBuilder() {
+        if (sliceConstraintsBuilder_ == null) {
+          sliceConstraintsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.Constraint, context.ContextOuterClass.Constraint.Builder, context.ContextOuterClass.ConstraintOrBuilder>(
+                  sliceConstraints_,
+                  ((bitField0_ & 0x00000002) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceConstraints_ = null;
+        }
+        return sliceConstraintsBuilder_;
+      }
+
+      private java.util.List<context.ContextOuterClass.ServiceId> sliceServiceIds_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceServiceIdsIsMutable() {
+        if (!((bitField0_ & 0x00000004) != 0)) {
+          sliceServiceIds_ = new java.util.ArrayList<context.ContextOuterClass.ServiceId>(sliceServiceIds_);
+          bitField0_ |= 0x00000004;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> sliceServiceIdsBuilder_;
+
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public java.util.List<context.ContextOuterClass.ServiceId> getSliceServiceIdsList() {
+        if (sliceServiceIdsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceServiceIds_);
+        } else {
+          return sliceServiceIdsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public int getSliceServiceIdsCount() {
+        if (sliceServiceIdsBuilder_ == null) {
+          return sliceServiceIds_.size();
+        } else {
+          return sliceServiceIdsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceId getSliceServiceIds(int index) {
+        if (sliceServiceIdsBuilder_ == null) {
+          return sliceServiceIds_.get(index);
+        } else {
+          return sliceServiceIdsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder setSliceServiceIds(
+          int index, context.ContextOuterClass.ServiceId value) {
+        if (sliceServiceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.set(index, value);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder setSliceServiceIds(
+          int index, context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addSliceServiceIds(context.ContextOuterClass.ServiceId value) {
+        if (sliceServiceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.add(value);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addSliceServiceIds(
+          int index, context.ContextOuterClass.ServiceId value) {
+        if (sliceServiceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.add(index, value);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addSliceServiceIds(
+          context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addSliceServiceIds(
+          int index, context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder addAllSliceServiceIds(
+          java.lang.Iterable<? extends context.ContextOuterClass.ServiceId> values) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceServiceIds_);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder clearSliceServiceIds() {
+        if (sliceServiceIdsBuilder_ == null) {
+          sliceServiceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000004);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public Builder removeSliceServiceIds(int index) {
+        if (sliceServiceIdsBuilder_ == null) {
+          ensureSliceServiceIdsIsMutable();
+          sliceServiceIds_.remove(index);
+          onChanged();
+        } else {
+          sliceServiceIdsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder getSliceServiceIdsBuilder(
+          int index) {
+        return getSliceServiceIdsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceIdOrBuilder getSliceServiceIdsOrBuilder(
+          int index) {
+        if (sliceServiceIdsBuilder_ == null) {
+          return sliceServiceIds_.get(index);  } else {
+          return sliceServiceIdsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.ServiceIdOrBuilder> 
+           getSliceServiceIdsOrBuilderList() {
+        if (sliceServiceIdsBuilder_ != null) {
+          return sliceServiceIdsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceServiceIds_);
+        }
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder addSliceServiceIdsBuilder() {
+        return getSliceServiceIdsFieldBuilder().addBuilder(
+            context.ContextOuterClass.ServiceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder addSliceServiceIdsBuilder(
+          int index) {
+        return getSliceServiceIdsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.ServiceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.ServiceId slice_service_ids = 4;</code>
+       */
+      public java.util.List<context.ContextOuterClass.ServiceId.Builder> 
+           getSliceServiceIdsBuilderList() {
+        return getSliceServiceIdsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> 
+          getSliceServiceIdsFieldBuilder() {
+        if (sliceServiceIdsBuilder_ == null) {
+          sliceServiceIdsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder>(
+                  sliceServiceIds_,
+                  ((bitField0_ & 0x00000004) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceServiceIds_ = null;
+        }
+        return sliceServiceIdsBuilder_;
+      }
+
+      private java.util.List<context.ContextOuterClass.SliceId> sliceSubsliceIds_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceSubsliceIdsIsMutable() {
+        if (!((bitField0_ & 0x00000008) != 0)) {
+          sliceSubsliceIds_ = new java.util.ArrayList<context.ContextOuterClass.SliceId>(sliceSubsliceIds_);
+          bitField0_ |= 0x00000008;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceSubsliceIdsBuilder_;
+
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public java.util.List<context.ContextOuterClass.SliceId> getSliceSubsliceIdsList() {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceSubsliceIds_);
+        } else {
+          return sliceSubsliceIdsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public int getSliceSubsliceIdsCount() {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          return sliceSubsliceIds_.size();
+        } else {
+          return sliceSubsliceIdsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceId getSliceSubsliceIds(int index) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          return sliceSubsliceIds_.get(index);
+        } else {
+          return sliceSubsliceIdsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder setSliceSubsliceIds(
+          int index, context.ContextOuterClass.SliceId value) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.set(index, value);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder setSliceSubsliceIds(
+          int index, context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addSliceSubsliceIds(context.ContextOuterClass.SliceId value) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.add(value);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addSliceSubsliceIds(
+          int index, context.ContextOuterClass.SliceId value) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.add(index, value);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addSliceSubsliceIds(
+          context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addSliceSubsliceIds(
+          int index, context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder addAllSliceSubsliceIds(
+          java.lang.Iterable<? extends context.ContextOuterClass.SliceId> values) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceSubsliceIds_);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder clearSliceSubsliceIds() {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          sliceSubsliceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000008);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public Builder removeSliceSubsliceIds(int index) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          ensureSliceSubsliceIdsIsMutable();
+          sliceSubsliceIds_.remove(index);
+          onChanged();
+        } else {
+          sliceSubsliceIdsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceSubsliceIdsBuilder(
+          int index) {
+        return getSliceSubsliceIdsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceIdOrBuilder getSliceSubsliceIdsOrBuilder(
+          int index) {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          return sliceSubsliceIds_.get(index);  } else {
+          return sliceSubsliceIdsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+           getSliceSubsliceIdsOrBuilderList() {
+        if (sliceSubsliceIdsBuilder_ != null) {
+          return sliceSubsliceIdsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceSubsliceIds_);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder addSliceSubsliceIdsBuilder() {
+        return getSliceSubsliceIdsFieldBuilder().addBuilder(
+            context.ContextOuterClass.SliceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder addSliceSubsliceIdsBuilder(
+          int index) {
+        return getSliceSubsliceIdsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.SliceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.SliceId slice_subslice_ids = 5;</code>
+       */
+      public java.util.List<context.ContextOuterClass.SliceId.Builder> 
+           getSliceSubsliceIdsBuilderList() {
+        return getSliceSubsliceIdsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> 
+          getSliceSubsliceIdsFieldBuilder() {
+        if (sliceSubsliceIdsBuilder_ == null) {
+          sliceSubsliceIdsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder>(
+                  sliceSubsliceIds_,
+                  ((bitField0_ & 0x00000008) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceSubsliceIds_ = null;
+        }
+        return sliceSubsliceIdsBuilder_;
+      }
+
+      private context.ContextOuterClass.SliceStatus sliceStatus_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceStatus, context.ContextOuterClass.SliceStatus.Builder, context.ContextOuterClass.SliceStatusOrBuilder> sliceStatusBuilder_;
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       * @return Whether the sliceStatus field is set.
+       */
+      public boolean hasSliceStatus() {
+        return sliceStatusBuilder_ != null || sliceStatus_ != null;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       * @return The sliceStatus.
+       */
+      public context.ContextOuterClass.SliceStatus getSliceStatus() {
+        if (sliceStatusBuilder_ == null) {
+          return sliceStatus_ == null ? context.ContextOuterClass.SliceStatus.getDefaultInstance() : sliceStatus_;
+        } else {
+          return sliceStatusBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public Builder setSliceStatus(context.ContextOuterClass.SliceStatus value) {
+        if (sliceStatusBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          sliceStatus_ = value;
+          onChanged();
+        } else {
+          sliceStatusBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public Builder setSliceStatus(
+          context.ContextOuterClass.SliceStatus.Builder builderForValue) {
+        if (sliceStatusBuilder_ == null) {
+          sliceStatus_ = builderForValue.build();
+          onChanged();
+        } else {
+          sliceStatusBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public Builder mergeSliceStatus(context.ContextOuterClass.SliceStatus value) {
+        if (sliceStatusBuilder_ == null) {
+          if (sliceStatus_ != null) {
+            sliceStatus_ =
+              context.ContextOuterClass.SliceStatus.newBuilder(sliceStatus_).mergeFrom(value).buildPartial();
+          } else {
+            sliceStatus_ = value;
+          }
+          onChanged();
+        } else {
+          sliceStatusBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public Builder clearSliceStatus() {
+        if (sliceStatusBuilder_ == null) {
+          sliceStatus_ = null;
+          onChanged();
+        } else {
+          sliceStatus_ = null;
+          sliceStatusBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public context.ContextOuterClass.SliceStatus.Builder getSliceStatusBuilder() {
+        
+        onChanged();
+        return getSliceStatusFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      public context.ContextOuterClass.SliceStatusOrBuilder getSliceStatusOrBuilder() {
+        if (sliceStatusBuilder_ != null) {
+          return sliceStatusBuilder_.getMessageOrBuilder();
+        } else {
+          return sliceStatus_ == null ?
+              context.ContextOuterClass.SliceStatus.getDefaultInstance() : sliceStatus_;
+        }
+      }
+      /**
+       * <code>.context.SliceStatus slice_status = 6;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceStatus, context.ContextOuterClass.SliceStatus.Builder, context.ContextOuterClass.SliceStatusOrBuilder> 
+          getSliceStatusFieldBuilder() {
+        if (sliceStatusBuilder_ == null) {
+          sliceStatusBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.SliceStatus, context.ContextOuterClass.SliceStatus.Builder, context.ContextOuterClass.SliceStatusOrBuilder>(
+                  getSliceStatus(),
+                  getParentForChildren(),
+                  isClean());
+          sliceStatus_ = null;
+        }
+        return sliceStatusBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.Slice)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.Slice)
+    private static final context.ContextOuterClass.Slice DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.Slice();
+    }
+
+    public static context.ContextOuterClass.Slice getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Slice>
+        PARSER = new com.google.protobuf.AbstractParser<Slice>() {
+      @java.lang.Override
+      public Slice parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Slice(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Slice> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Slice> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.Slice getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceStatusOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceStatus)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.SliceStatusEnum slice_status = 1;</code>
+     * @return The enum numeric value on the wire for sliceStatus.
+     */
+    int getSliceStatusValue();
+    /**
+     * <code>.context.SliceStatusEnum slice_status = 1;</code>
+     * @return The sliceStatus.
+     */
+    context.ContextOuterClass.SliceStatusEnum getSliceStatus();
+  }
+  /**
+   * Protobuf type {@code context.SliceStatus}
+   */
+  public static final class SliceStatus extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.SliceStatus)
+      SliceStatusOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use SliceStatus.newBuilder() to construct.
+    private SliceStatus(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private SliceStatus() {
+      sliceStatus_ = 0;
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new SliceStatus();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SliceStatus(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 8: {
+              int rawValue = input.readEnum();
+
+              sliceStatus_ = rawValue;
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_SliceStatus_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_SliceStatus_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.SliceStatus.class, context.ContextOuterClass.SliceStatus.Builder.class);
+    }
+
+    public static final int SLICE_STATUS_FIELD_NUMBER = 1;
+    private int sliceStatus_;
+    /**
+     * <code>.context.SliceStatusEnum slice_status = 1;</code>
+     * @return The enum numeric value on the wire for sliceStatus.
+     */
+    @java.lang.Override public int getSliceStatusValue() {
+      return sliceStatus_;
+    }
+    /**
+     * <code>.context.SliceStatusEnum slice_status = 1;</code>
+     * @return The sliceStatus.
+     */
+    @java.lang.Override public context.ContextOuterClass.SliceStatusEnum getSliceStatus() {
+      @SuppressWarnings("deprecation")
+      context.ContextOuterClass.SliceStatusEnum result = context.ContextOuterClass.SliceStatusEnum.valueOf(sliceStatus_);
+      return result == null ? context.ContextOuterClass.SliceStatusEnum.UNRECOGNIZED : result;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (sliceStatus_ != context.ContextOuterClass.SliceStatusEnum.SLICESTATUS_UNDEFINED.getNumber()) {
+        output.writeEnum(1, sliceStatus_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (sliceStatus_ != context.ContextOuterClass.SliceStatusEnum.SLICESTATUS_UNDEFINED.getNumber()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(1, sliceStatus_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.SliceStatus)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.SliceStatus other = (context.ContextOuterClass.SliceStatus) obj;
+
+      if (sliceStatus_ != other.sliceStatus_) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + SLICE_STATUS_FIELD_NUMBER;
+      hash = (53 * hash) + sliceStatus_;
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceStatus parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceStatus parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.SliceStatus prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.SliceStatus}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.SliceStatus)
+        context.ContextOuterClass.SliceStatusOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_SliceStatus_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_SliceStatus_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.SliceStatus.class, context.ContextOuterClass.SliceStatus.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.SliceStatus.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        sliceStatus_ = 0;
+
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_SliceStatus_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceStatus getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceStatus.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceStatus build() {
+        context.ContextOuterClass.SliceStatus result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceStatus buildPartial() {
+        context.ContextOuterClass.SliceStatus result = new context.ContextOuterClass.SliceStatus(this);
+        result.sliceStatus_ = sliceStatus_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceStatus) {
+          return mergeFrom((context.ContextOuterClass.SliceStatus)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceStatus other) {
+        if (other == context.ContextOuterClass.SliceStatus.getDefaultInstance()) return this;
+        if (other.sliceStatus_ != 0) {
+          setSliceStatusValue(other.getSliceStatusValue());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceStatus parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceStatus) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private int sliceStatus_ = 0;
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @return The enum numeric value on the wire for sliceStatus.
+       */
+      @java.lang.Override public int getSliceStatusValue() {
+        return sliceStatus_;
+      }
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @param value The enum numeric value on the wire for sliceStatus to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSliceStatusValue(int value) {
+        
+        sliceStatus_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @return The sliceStatus.
+       */
+      @java.lang.Override
+      public context.ContextOuterClass.SliceStatusEnum getSliceStatus() {
+        @SuppressWarnings("deprecation")
+        context.ContextOuterClass.SliceStatusEnum result = context.ContextOuterClass.SliceStatusEnum.valueOf(sliceStatus_);
+        return result == null ? context.ContextOuterClass.SliceStatusEnum.UNRECOGNIZED : result;
+      }
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @param value The sliceStatus to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSliceStatus(context.ContextOuterClass.SliceStatusEnum value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        
+        sliceStatus_ = value.getNumber();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.context.SliceStatusEnum slice_status = 1;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSliceStatus() {
+        
+        sliceStatus_ = 0;
+        onChanged();
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceStatus)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceStatus)
+    private static final context.ContextOuterClass.SliceStatus DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceStatus();
+    }
+
+    public static context.ContextOuterClass.SliceStatus getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceStatus>
+        PARSER = new com.google.protobuf.AbstractParser<SliceStatus>() {
+      @java.lang.Override
+      public SliceStatus parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceStatus(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceStatus> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceStatus> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceStatus getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceIdListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceIdList)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    java.util.List<context.ContextOuterClass.SliceId> 
+        getSliceIdsList();
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    context.ContextOuterClass.SliceId getSliceIds(int index);
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    int getSliceIdsCount();
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+        getSliceIdsOrBuilderList();
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    context.ContextOuterClass.SliceIdOrBuilder getSliceIdsOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code context.SliceIdList}
+   */
+  public static final class SliceIdList extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.SliceIdList)
+      SliceIdListOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use SliceIdList.newBuilder() to construct.
+    private SliceIdList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private SliceIdList() {
+      sliceIds_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new SliceIdList();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SliceIdList(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                sliceIds_ = new java.util.ArrayList<context.ContextOuterClass.SliceId>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              sliceIds_.add(
+                  input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry));
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          sliceIds_ = java.util.Collections.unmodifiableList(sliceIds_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_SliceIdList_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_SliceIdList_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.SliceIdList.class, context.ContextOuterClass.SliceIdList.Builder.class);
+    }
+
+    public static final int SLICE_IDS_FIELD_NUMBER = 1;
+    private java.util.List<context.ContextOuterClass.SliceId> sliceIds_;
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.SliceId> getSliceIdsList() {
+      return sliceIds_;
+    }
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+        getSliceIdsOrBuilderList() {
+      return sliceIds_;
+    }
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public int getSliceIdsCount() {
+      return sliceIds_.size();
+    }
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getSliceIds(int index) {
+      return sliceIds_.get(index);
+    }
+    /**
+     * <code>repeated .context.SliceId slice_ids = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdOrBuilder getSliceIdsOrBuilder(
+        int index) {
+      return sliceIds_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < sliceIds_.size(); i++) {
+        output.writeMessage(1, sliceIds_.get(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < sliceIds_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, sliceIds_.get(i));
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.SliceIdList)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.SliceIdList other = (context.ContextOuterClass.SliceIdList) obj;
+
+      if (!getSliceIdsList()
+          .equals(other.getSliceIdsList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getSliceIdsCount() > 0) {
+        hash = (37 * hash) + SLICE_IDS_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceIdsList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceIdList parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceIdList parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.SliceIdList prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.SliceIdList}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.SliceIdList)
+        context.ContextOuterClass.SliceIdListOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_SliceIdList_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_SliceIdList_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.SliceIdList.class, context.ContextOuterClass.SliceIdList.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.SliceIdList.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getSliceIdsFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (sliceIdsBuilder_ == null) {
+          sliceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          sliceIdsBuilder_.clear();
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_SliceIdList_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceIdList getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceIdList.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceIdList build() {
+        context.ContextOuterClass.SliceIdList result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceIdList buildPartial() {
+        context.ContextOuterClass.SliceIdList result = new context.ContextOuterClass.SliceIdList(this);
+        int from_bitField0_ = bitField0_;
+        if (sliceIdsBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            sliceIds_ = java.util.Collections.unmodifiableList(sliceIds_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.sliceIds_ = sliceIds_;
+        } else {
+          result.sliceIds_ = sliceIdsBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceIdList) {
+          return mergeFrom((context.ContextOuterClass.SliceIdList)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceIdList other) {
+        if (other == context.ContextOuterClass.SliceIdList.getDefaultInstance()) return this;
+        if (sliceIdsBuilder_ == null) {
+          if (!other.sliceIds_.isEmpty()) {
+            if (sliceIds_.isEmpty()) {
+              sliceIds_ = other.sliceIds_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureSliceIdsIsMutable();
+              sliceIds_.addAll(other.sliceIds_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.sliceIds_.isEmpty()) {
+            if (sliceIdsBuilder_.isEmpty()) {
+              sliceIdsBuilder_.dispose();
+              sliceIdsBuilder_ = null;
+              sliceIds_ = other.sliceIds_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              sliceIdsBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSliceIdsFieldBuilder() : null;
+            } else {
+              sliceIdsBuilder_.addAllMessages(other.sliceIds_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceIdList parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceIdList) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.util.List<context.ContextOuterClass.SliceId> sliceIds_ =
+        java.util.Collections.emptyList();
+      private void ensureSliceIdsIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          sliceIds_ = new java.util.ArrayList<context.ContextOuterClass.SliceId>(sliceIds_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceIdsBuilder_;
+
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public java.util.List<context.ContextOuterClass.SliceId> getSliceIdsList() {
+        if (sliceIdsBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(sliceIds_);
+        } else {
+          return sliceIdsBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public int getSliceIdsCount() {
+        if (sliceIdsBuilder_ == null) {
+          return sliceIds_.size();
+        } else {
+          return sliceIdsBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId getSliceIds(int index) {
+        if (sliceIdsBuilder_ == null) {
+          return sliceIds_.get(index);
+        } else {
+          return sliceIdsBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder setSliceIds(
+          int index, context.ContextOuterClass.SliceId value) {
+        if (sliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceIdsIsMutable();
+          sliceIds_.set(index, value);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder setSliceIds(
+          int index, context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          sliceIds_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceIdsBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addSliceIds(context.ContextOuterClass.SliceId value) {
+        if (sliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceIdsIsMutable();
+          sliceIds_.add(value);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addSliceIds(
+          int index, context.ContextOuterClass.SliceId value) {
+        if (sliceIdsBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSliceIdsIsMutable();
+          sliceIds_.add(index, value);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addSliceIds(
+          context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          sliceIds_.add(builderForValue.build());
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addSliceIds(
+          int index, context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          sliceIds_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder addAllSliceIds(
+          java.lang.Iterable<? extends context.ContextOuterClass.SliceId> values) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, sliceIds_);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder clearSliceIds() {
+        if (sliceIdsBuilder_ == null) {
+          sliceIds_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public Builder removeSliceIds(int index) {
+        if (sliceIdsBuilder_ == null) {
+          ensureSliceIdsIsMutable();
+          sliceIds_.remove(index);
+          onChanged();
+        } else {
+          sliceIdsBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceIdsBuilder(
+          int index) {
+        return getSliceIdsFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceIdOrBuilder getSliceIdsOrBuilder(
+          int index) {
+        if (sliceIdsBuilder_ == null) {
+          return sliceIds_.get(index);  } else {
+          return sliceIdsBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.SliceIdOrBuilder> 
+           getSliceIdsOrBuilderList() {
+        if (sliceIdsBuilder_ != null) {
+          return sliceIdsBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(sliceIds_);
+        }
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder addSliceIdsBuilder() {
+        return getSliceIdsFieldBuilder().addBuilder(
+            context.ContextOuterClass.SliceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder addSliceIdsBuilder(
+          int index) {
+        return getSliceIdsFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.SliceId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.SliceId slice_ids = 1;</code>
+       */
+      public java.util.List<context.ContextOuterClass.SliceId.Builder> 
+           getSliceIdsBuilderList() {
+        return getSliceIdsFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> 
+          getSliceIdsFieldBuilder() {
+        if (sliceIdsBuilder_ == null) {
+          sliceIdsBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder>(
+                  sliceIds_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          sliceIds_ = null;
+        }
+        return sliceIdsBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceIdList)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceIdList)
+    private static final context.ContextOuterClass.SliceIdList DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceIdList();
+    }
+
+    public static context.ContextOuterClass.SliceIdList getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceIdList>
+        PARSER = new com.google.protobuf.AbstractParser<SliceIdList>() {
+      @java.lang.Override
+      public SliceIdList parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceIdList(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceIdList> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceIdList> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdList getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceList)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    java.util.List<context.ContextOuterClass.Slice> 
+        getSlicesList();
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    context.ContextOuterClass.Slice getSlices(int index);
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    int getSlicesCount();
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.SliceOrBuilder> 
+        getSlicesOrBuilderList();
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    context.ContextOuterClass.SliceOrBuilder getSlicesOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code context.SliceList}
+   */
+  public static final class SliceList extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.SliceList)
+      SliceListOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use SliceList.newBuilder() to construct.
+    private SliceList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private SliceList() {
+      slices_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new SliceList();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SliceList(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                slices_ = new java.util.ArrayList<context.ContextOuterClass.Slice>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              slices_.add(
+                  input.readMessage(context.ContextOuterClass.Slice.parser(), extensionRegistry));
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          slices_ = java.util.Collections.unmodifiableList(slices_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_SliceList_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_SliceList_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.SliceList.class, context.ContextOuterClass.SliceList.Builder.class);
+    }
+
+    public static final int SLICES_FIELD_NUMBER = 1;
+    private java.util.List<context.ContextOuterClass.Slice> slices_;
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.Slice> getSlicesList() {
+      return slices_;
+    }
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.SliceOrBuilder> 
+        getSlicesOrBuilderList() {
+      return slices_;
+    }
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public int getSlicesCount() {
+      return slices_.size();
+    }
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Slice getSlices(int index) {
+      return slices_.get(index);
+    }
+    /**
+     * <code>repeated .context.Slice slices = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceOrBuilder getSlicesOrBuilder(
+        int index) {
+      return slices_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < slices_.size(); i++) {
+        output.writeMessage(1, slices_.get(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < slices_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, slices_.get(i));
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.SliceList)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.SliceList other = (context.ContextOuterClass.SliceList) obj;
+
+      if (!getSlicesList()
+          .equals(other.getSlicesList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getSlicesCount() > 0) {
+        hash = (37 * hash) + SLICES_FIELD_NUMBER;
+        hash = (53 * hash) + getSlicesList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.SliceList parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceList parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceList parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.SliceList prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.SliceList}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.SliceList)
+        context.ContextOuterClass.SliceListOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_SliceList_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_SliceList_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.SliceList.class, context.ContextOuterClass.SliceList.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.SliceList.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getSlicesFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (slicesBuilder_ == null) {
+          slices_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          slicesBuilder_.clear();
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_SliceList_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceList getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceList.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceList build() {
+        context.ContextOuterClass.SliceList result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceList buildPartial() {
+        context.ContextOuterClass.SliceList result = new context.ContextOuterClass.SliceList(this);
+        int from_bitField0_ = bitField0_;
+        if (slicesBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            slices_ = java.util.Collections.unmodifiableList(slices_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.slices_ = slices_;
+        } else {
+          result.slices_ = slicesBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceList) {
+          return mergeFrom((context.ContextOuterClass.SliceList)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceList other) {
+        if (other == context.ContextOuterClass.SliceList.getDefaultInstance()) return this;
+        if (slicesBuilder_ == null) {
+          if (!other.slices_.isEmpty()) {
+            if (slices_.isEmpty()) {
+              slices_ = other.slices_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureSlicesIsMutable();
+              slices_.addAll(other.slices_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.slices_.isEmpty()) {
+            if (slicesBuilder_.isEmpty()) {
+              slicesBuilder_.dispose();
+              slicesBuilder_ = null;
+              slices_ = other.slices_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              slicesBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getSlicesFieldBuilder() : null;
+            } else {
+              slicesBuilder_.addAllMessages(other.slices_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceList parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceList) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.util.List<context.ContextOuterClass.Slice> slices_ =
+        java.util.Collections.emptyList();
+      private void ensureSlicesIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          slices_ = new java.util.ArrayList<context.ContextOuterClass.Slice>(slices_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.Slice, context.ContextOuterClass.Slice.Builder, context.ContextOuterClass.SliceOrBuilder> slicesBuilder_;
+
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public java.util.List<context.ContextOuterClass.Slice> getSlicesList() {
+        if (slicesBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(slices_);
+        } else {
+          return slicesBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public int getSlicesCount() {
+        if (slicesBuilder_ == null) {
+          return slices_.size();
+        } else {
+          return slicesBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.Slice getSlices(int index) {
+        if (slicesBuilder_ == null) {
+          return slices_.get(index);
+        } else {
+          return slicesBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder setSlices(
+          int index, context.ContextOuterClass.Slice value) {
+        if (slicesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSlicesIsMutable();
+          slices_.set(index, value);
+          onChanged();
+        } else {
+          slicesBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder setSlices(
+          int index, context.ContextOuterClass.Slice.Builder builderForValue) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          slices_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          slicesBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addSlices(context.ContextOuterClass.Slice value) {
+        if (slicesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSlicesIsMutable();
+          slices_.add(value);
+          onChanged();
+        } else {
+          slicesBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addSlices(
+          int index, context.ContextOuterClass.Slice value) {
+        if (slicesBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureSlicesIsMutable();
+          slices_.add(index, value);
+          onChanged();
+        } else {
+          slicesBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addSlices(
+          context.ContextOuterClass.Slice.Builder builderForValue) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          slices_.add(builderForValue.build());
+          onChanged();
+        } else {
+          slicesBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addSlices(
+          int index, context.ContextOuterClass.Slice.Builder builderForValue) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          slices_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          slicesBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder addAllSlices(
+          java.lang.Iterable<? extends context.ContextOuterClass.Slice> values) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, slices_);
+          onChanged();
+        } else {
+          slicesBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder clearSlices() {
+        if (slicesBuilder_ == null) {
+          slices_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          slicesBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public Builder removeSlices(int index) {
+        if (slicesBuilder_ == null) {
+          ensureSlicesIsMutable();
+          slices_.remove(index);
+          onChanged();
+        } else {
+          slicesBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.Slice.Builder getSlicesBuilder(
+          int index) {
+        return getSlicesFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.SliceOrBuilder getSlicesOrBuilder(
+          int index) {
+        if (slicesBuilder_ == null) {
+          return slices_.get(index);  } else {
+          return slicesBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.SliceOrBuilder> 
+           getSlicesOrBuilderList() {
+        if (slicesBuilder_ != null) {
+          return slicesBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(slices_);
+        }
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.Slice.Builder addSlicesBuilder() {
+        return getSlicesFieldBuilder().addBuilder(
+            context.ContextOuterClass.Slice.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public context.ContextOuterClass.Slice.Builder addSlicesBuilder(
+          int index) {
+        return getSlicesFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.Slice.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .context.Slice slices = 1;</code>
+       */
+      public java.util.List<context.ContextOuterClass.Slice.Builder> 
+           getSlicesBuilderList() {
+        return getSlicesFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.Slice, context.ContextOuterClass.Slice.Builder, context.ContextOuterClass.SliceOrBuilder> 
+          getSlicesFieldBuilder() {
+        if (slicesBuilder_ == null) {
+          slicesBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.Slice, context.ContextOuterClass.Slice.Builder, context.ContextOuterClass.SliceOrBuilder>(
+                  slices_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          slices_ = null;
+        }
+        return slicesBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceList)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceList)
+    private static final context.ContextOuterClass.SliceList DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceList();
+    }
+
+    public static context.ContextOuterClass.SliceList getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceList>
+        PARSER = new com.google.protobuf.AbstractParser<SliceList>() {
+      @java.lang.Override
+      public SliceList parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceList(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceList> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceList> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceList getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface SliceEventOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.SliceEvent)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.Event event = 1;</code>
+     * @return Whether the event field is set.
+     */
+    boolean hasEvent();
+    /**
+     * <code>.context.Event event = 1;</code>
+     * @return The event.
+     */
+    context.ContextOuterClass.Event getEvent();
+    /**
+     * <code>.context.Event event = 1;</code>
+     */
+    context.ContextOuterClass.EventOrBuilder getEventOrBuilder();
+
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     * @return Whether the sliceId field is set.
+     */
+    boolean hasSliceId();
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     * @return The sliceId.
+     */
+    context.ContextOuterClass.SliceId getSliceId();
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     */
+    context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder();
+  }
+  /**
+   * Protobuf type {@code context.SliceEvent}
+   */
+  public static final class SliceEvent extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.SliceEvent)
+      SliceEventOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use SliceEvent.newBuilder() to construct.
+    private SliceEvent(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private SliceEvent() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new SliceEvent();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private SliceEvent(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              context.ContextOuterClass.Event.Builder subBuilder = null;
+              if (event_ != null) {
+                subBuilder = event_.toBuilder();
+              }
+              event_ = input.readMessage(context.ContextOuterClass.Event.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(event_);
+                event_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              context.ContextOuterClass.SliceId.Builder subBuilder = null;
+              if (sliceId_ != null) {
+                subBuilder = sliceId_.toBuilder();
+              }
+              sliceId_ = input.readMessage(context.ContextOuterClass.SliceId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(sliceId_);
+                sliceId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_SliceEvent_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_SliceEvent_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.SliceEvent.class, context.ContextOuterClass.SliceEvent.Builder.class);
+    }
+
+    public static final int EVENT_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Event event_;
+    /**
+     * <code>.context.Event event = 1;</code>
+     * @return Whether the event field is set.
+     */
+    @java.lang.Override
+    public boolean hasEvent() {
+      return event_ != null;
+    }
+    /**
+     * <code>.context.Event event = 1;</code>
+     * @return The event.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Event getEvent() {
+      return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
+    }
+    /**
+     * <code>.context.Event event = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
+      return getEvent();
+    }
+
+    public static final int SLICE_ID_FIELD_NUMBER = 2;
+    private context.ContextOuterClass.SliceId sliceId_;
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     * @return Whether the sliceId field is set.
+     */
+    @java.lang.Override
+    public boolean hasSliceId() {
+      return sliceId_ != null;
+    }
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     * @return The sliceId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceId getSliceId() {
+      return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+    }
+    /**
+     * <code>.context.SliceId slice_id = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
+      return getSliceId();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (event_ != null) {
+        output.writeMessage(1, getEvent());
+      }
+      if (sliceId_ != null) {
+        output.writeMessage(2, getSliceId());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (event_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getEvent());
+      }
+      if (sliceId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getSliceId());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.SliceEvent)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.SliceEvent other = (context.ContextOuterClass.SliceEvent) obj;
+
+      if (hasEvent() != other.hasEvent()) return false;
+      if (hasEvent()) {
+        if (!getEvent()
+            .equals(other.getEvent())) return false;
+      }
+      if (hasSliceId() != other.hasSliceId()) return false;
+      if (hasSliceId()) {
+        if (!getSliceId()
+            .equals(other.getSliceId())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasEvent()) {
+        hash = (37 * hash) + EVENT_FIELD_NUMBER;
+        hash = (53 * hash) + getEvent().hashCode();
+      }
+      if (hasSliceId()) {
+        hash = (37 * hash) + SLICE_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getSliceId().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceEvent parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.SliceEvent parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.SliceEvent prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code context.SliceEvent}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.SliceEvent)
+        context.ContextOuterClass.SliceEventOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_SliceEvent_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_SliceEvent_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.SliceEvent.class, context.ContextOuterClass.SliceEvent.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.SliceEvent.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (eventBuilder_ == null) {
+          event_ = null;
+        } else {
+          event_ = null;
+          eventBuilder_ = null;
+        }
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_SliceEvent_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceEvent getDefaultInstanceForType() {
+        return context.ContextOuterClass.SliceEvent.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceEvent build() {
+        context.ContextOuterClass.SliceEvent result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.SliceEvent buildPartial() {
+        context.ContextOuterClass.SliceEvent result = new context.ContextOuterClass.SliceEvent(this);
+        if (eventBuilder_ == null) {
+          result.event_ = event_;
+        } else {
+          result.event_ = eventBuilder_.build();
+        }
+        if (sliceIdBuilder_ == null) {
+          result.sliceId_ = sliceId_;
+        } else {
+          result.sliceId_ = sliceIdBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof context.ContextOuterClass.SliceEvent) {
+          return mergeFrom((context.ContextOuterClass.SliceEvent)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(context.ContextOuterClass.SliceEvent other) {
+        if (other == context.ContextOuterClass.SliceEvent.getDefaultInstance()) return this;
+        if (other.hasEvent()) {
+          mergeEvent(other.getEvent());
+        }
+        if (other.hasSliceId()) {
+          mergeSliceId(other.getSliceId());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        context.ContextOuterClass.SliceEvent parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (context.ContextOuterClass.SliceEvent) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private context.ContextOuterClass.Event event_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> eventBuilder_;
+      /**
+       * <code>.context.Event event = 1;</code>
+       * @return Whether the event field is set.
+       */
+      public boolean hasEvent() {
+        return eventBuilder_ != null || event_ != null;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       * @return The event.
+       */
+      public context.ContextOuterClass.Event getEvent() {
+        if (eventBuilder_ == null) {
+          return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
+        } else {
+          return eventBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public Builder setEvent(context.ContextOuterClass.Event value) {
+        if (eventBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          event_ = value;
+          onChanged();
+        } else {
+          eventBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public Builder setEvent(
+          context.ContextOuterClass.Event.Builder builderForValue) {
+        if (eventBuilder_ == null) {
+          event_ = builderForValue.build();
+          onChanged();
+        } else {
+          eventBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public Builder mergeEvent(context.ContextOuterClass.Event value) {
+        if (eventBuilder_ == null) {
+          if (event_ != null) {
+            event_ =
+              context.ContextOuterClass.Event.newBuilder(event_).mergeFrom(value).buildPartial();
+          } else {
+            event_ = value;
+          }
+          onChanged();
+        } else {
+          eventBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public Builder clearEvent() {
+        if (eventBuilder_ == null) {
+          event_ = null;
+          onChanged();
+        } else {
+          event_ = null;
+          eventBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public context.ContextOuterClass.Event.Builder getEventBuilder() {
+        
+        onChanged();
+        return getEventFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
+        if (eventBuilder_ != null) {
+          return eventBuilder_.getMessageOrBuilder();
+        } else {
+          return event_ == null ?
+              context.ContextOuterClass.Event.getDefaultInstance() : event_;
+        }
+      }
+      /**
+       * <code>.context.Event event = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> 
+          getEventFieldBuilder() {
+        if (eventBuilder_ == null) {
+          eventBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder>(
+                  getEvent(),
+                  getParentForChildren(),
+                  isClean());
+          event_ = null;
+        }
+        return eventBuilder_;
+      }
+
+      private context.ContextOuterClass.SliceId sliceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> sliceIdBuilder_;
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       * @return Whether the sliceId field is set.
+       */
+      public boolean hasSliceId() {
+        return sliceIdBuilder_ != null || sliceId_ != null;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       * @return The sliceId.
+       */
+      public context.ContextOuterClass.SliceId getSliceId() {
+        if (sliceIdBuilder_ == null) {
+          return sliceId_ == null ? context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+        } else {
+          return sliceIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public Builder setSliceId(context.ContextOuterClass.SliceId value) {
+        if (sliceIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          sliceId_ = value;
+          onChanged();
+        } else {
+          sliceIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public Builder setSliceId(
+          context.ContextOuterClass.SliceId.Builder builderForValue) {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = builderForValue.build();
+          onChanged();
+        } else {
+          sliceIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public Builder mergeSliceId(context.ContextOuterClass.SliceId value) {
+        if (sliceIdBuilder_ == null) {
+          if (sliceId_ != null) {
+            sliceId_ =
+              context.ContextOuterClass.SliceId.newBuilder(sliceId_).mergeFrom(value).buildPartial();
+          } else {
+            sliceId_ = value;
+          }
+          onChanged();
+        } else {
+          sliceIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public Builder clearSliceId() {
+        if (sliceIdBuilder_ == null) {
+          sliceId_ = null;
+          onChanged();
+        } else {
+          sliceId_ = null;
+          sliceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public context.ContextOuterClass.SliceId.Builder getSliceIdBuilder() {
+        
+        onChanged();
+        return getSliceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      public context.ContextOuterClass.SliceIdOrBuilder getSliceIdOrBuilder() {
+        if (sliceIdBuilder_ != null) {
+          return sliceIdBuilder_.getMessageOrBuilder();
+        } else {
+          return sliceId_ == null ?
+              context.ContextOuterClass.SliceId.getDefaultInstance() : sliceId_;
+        }
+      }
+      /**
+       * <code>.context.SliceId slice_id = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder> 
+          getSliceIdFieldBuilder() {
+        if (sliceIdBuilder_ == null) {
+          sliceIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.SliceId, context.ContextOuterClass.SliceId.Builder, context.ContextOuterClass.SliceIdOrBuilder>(
+                  getSliceId(),
+                  getParentForChildren(),
+                  isClean());
+          sliceId_ = null;
+        }
+        return sliceIdBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:context.SliceEvent)
+    }
+
+    // @@protoc_insertion_point(class_scope:context.SliceEvent)
+    private static final context.ContextOuterClass.SliceEvent DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new context.ContextOuterClass.SliceEvent();
+    }
+
+    public static context.ContextOuterClass.SliceEvent getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<SliceEvent>
+        PARSER = new com.google.protobuf.AbstractParser<SliceEvent>() {
+      @java.lang.Override
+      public SliceEvent parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new SliceEvent(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<SliceEvent> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<SliceEvent> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public context.ContextOuterClass.SliceEvent getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface ConnectionIdOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:context.ConnectionId)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     * @return Whether the connectionUuid field is set.
+     */
+    boolean hasConnectionUuid();
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     * @return The connectionUuid.
+     */
+    context.ContextOuterClass.Uuid getConnectionUuid();
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     */
+    context.ContextOuterClass.UuidOrBuilder getConnectionUuidOrBuilder();
+  }
+  /**
+   * <pre>
+   * ----- Connection ----------------------------------------------------------------------------------------------------
+   * </pre>
+   *
+   * Protobuf type {@code context.ConnectionId}
+   */
+  public static final class ConnectionId extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:context.ConnectionId)
+      ConnectionIdOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use ConnectionId.newBuilder() to construct.
+    private ConnectionId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private ConnectionId() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new ConnectionId();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private ConnectionId(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              context.ContextOuterClass.Uuid.Builder subBuilder = null;
+              if (connectionUuid_ != null) {
+                subBuilder = connectionUuid_.toBuilder();
+              }
+              connectionUuid_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(connectionUuid_);
+                connectionUuid_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return context.ContextOuterClass.internal_static_context_ConnectionId_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              context.ContextOuterClass.ConnectionId.class, context.ContextOuterClass.ConnectionId.Builder.class);
+    }
+
+    public static final int CONNECTION_UUID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Uuid connectionUuid_;
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     * @return Whether the connectionUuid field is set.
+     */
+    @java.lang.Override
+    public boolean hasConnectionUuid() {
+      return connectionUuid_ != null;
+    }
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     * @return The connectionUuid.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Uuid getConnectionUuid() {
+      return connectionUuid_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : connectionUuid_;
+    }
+    /**
+     * <code>.context.Uuid connection_uuid = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.UuidOrBuilder getConnectionUuidOrBuilder() {
+      return getConnectionUuid();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (connectionUuid_ != null) {
+        output.writeMessage(1, getConnectionUuid());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (connectionUuid_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getConnectionUuid());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof context.ContextOuterClass.ConnectionId)) {
+        return super.equals(obj);
+      }
+      context.ContextOuterClass.ConnectionId other = (context.ContextOuterClass.ConnectionId) obj;
+
+      if (hasConnectionUuid() != other.hasConnectionUuid()) return false;
+      if (hasConnectionUuid()) {
+        if (!getConnectionUuid()
+            .equals(other.getConnectionUuid())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasConnectionUuid()) {
+        hash = (37 * hash) + CONNECTION_UUID_FIELD_NUMBER;
+        hash = (53 * hash) + getConnectionUuid().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.ConnectionId parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static context.ContextOuterClass.ConnectionId parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(context.ContextOuterClass.ConnectionId prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * ----- Connection ----------------------------------------------------------------------------------------------------
+     * </pre>
+     *
+     * Protobuf type {@code context.ConnectionId}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:context.ConnectionId)
+        context.ContextOuterClass.ConnectionIdOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return context.ContextOuterClass.internal_static_context_ConnectionId_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                context.ContextOuterClass.ConnectionId.class, context.ContextOuterClass.ConnectionId.Builder.class);
+      }
+
+      // Construct using context.ContextOuterClass.ConnectionId.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (connectionUuidBuilder_ == null) {
+          connectionUuid_ = null;
+        } else {
+          connectionUuid_ = null;
+          connectionUuidBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return context.ContextOuterClass.internal_static_context_ConnectionId_descriptor;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.ConnectionId getDefaultInstanceForType() {
+        return context.ContextOuterClass.ConnectionId.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.ConnectionId build() {
+        context.ContextOuterClass.ConnectionId result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public context.ContextOuterClass.ConnectionId buildPartial() {
+        context.ContextOuterClass.ConnectionId result = new context.ContextOuterClass.ConnectionId(this);
+        if (connectionUuidBuilder_ == null) {
+          result.connectionUuid_ = connectionUuid_;
+        } else {
+          result.connectionUuid_ = connectionUuidBuilder_.build();
         }
         onBuilt();
         return result;
@@ -37615,6 +43832,36 @@ public final class ContextOuterClass {
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_context_ServiceEvent_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceId_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceId_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_Slice_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_Slice_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceStatus_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceStatus_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceIdList_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceIdList_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceList_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceList_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_context_SliceEvent_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_context_SliceEvent_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_context_ConnectionId_descriptor;
   private static final 
@@ -37744,107 +43991,134 @@ public final class ContextOuterClass {
       "\"\n\010services\030\001 \003(\0132\020.context.Service\"U\n\014S" +
       "erviceEvent\022\035\n\005event\030\001 \001(\0132\016.context.Eve" +
       "nt\022&\n\nservice_id\030\002 \001(\0132\022.context.Service" +
-      "Id\"6\n\014ConnectionId\022&\n\017connection_uuid\030\001 " +
-      "\001(\0132\r.context.Uuid\"\304\001\n\nConnection\022,\n\rcon" +
-      "nection_id\030\001 \001(\0132\025.context.ConnectionId\022" +
-      "&\n\nservice_id\030\002 \001(\0132\022.context.ServiceId\022" +
-      "3\n\026path_hops_endpoint_ids\030\003 \003(\0132\023.contex" +
-      "t.EndPointId\022+\n\017sub_service_ids\030\004 \003(\0132\022." +
-      "context.ServiceId\"A\n\020ConnectionIdList\022-\n" +
-      "\016connection_ids\030\001 \003(\0132\025.context.Connecti" +
-      "onId\":\n\016ConnectionList\022(\n\013connections\030\001 " +
-      "\003(\0132\023.context.Connection\"^\n\017ConnectionEv" +
-      "ent\022\035\n\005event\030\001 \001(\0132\016.context.Event\022,\n\rco" +
-      "nnection_id\030\002 \001(\0132\025.context.ConnectionId" +
-      "\"\202\001\n\nEndPointId\022(\n\013topology_id\030\001 \001(\0132\023.c" +
-      "ontext.TopologyId\022$\n\tdevice_id\030\002 \001(\0132\021.c" +
-      "ontext.DeviceId\022$\n\rendpoint_uuid\030\003 \001(\0132\r" +
-      ".context.Uuid\"\206\001\n\010EndPoint\022(\n\013endpoint_i" +
-      "d\030\001 \001(\0132\023.context.EndPointId\022\025\n\rendpoint" +
-      "_type\030\002 \001(\t\0229\n\020kpi_sample_types\030\003 \003(\0162\037." +
-      "kpi_sample_types.KpiSampleType\"e\n\nConfig" +
-      "Rule\022)\n\006action\030\001 \001(\0162\031.context.ConfigAct" +
-      "ionEnum\022\024\n\014resource_key\030\002 \001(\t\022\026\n\016resourc" +
-      "e_value\030\003 \001(\t\"?\n\nConstraint\022\027\n\017constrain" +
-      "t_type\030\001 \001(\t\022\030\n\020constraint_value\030\002 \001(\t\"^" +
-      "\n\022TeraFlowController\022&\n\ncontext_id\030\001 \001(\013" +
-      "2\022.context.ContextId\022\022\n\nip_address\030\002 \001(\t" +
-      "\022\014\n\004port\030\003 \001(\r\"U\n\024AuthenticationResult\022&" +
-      "\n\ncontext_id\030\001 \001(\0132\022.context.ContextId\022\025" +
-      "\n\rauthenticated\030\002 \001(\010*j\n\rEventTypeEnum\022\027" +
-      "\n\023EVENTTYPE_UNDEFINED\020\000\022\024\n\020EVENTTYPE_CRE" +
-      "ATE\020\001\022\024\n\020EVENTTYPE_UPDATE\020\002\022\024\n\020EVENTTYPE" +
-      "_REMOVE\020\003*\305\001\n\020DeviceDriverEnum\022\032\n\026DEVICE" +
-      "DRIVER_UNDEFINED\020\000\022\033\n\027DEVICEDRIVER_OPENC" +
-      "ONFIG\020\001\022\036\n\032DEVICEDRIVER_TRANSPORT_API\020\002\022" +
-      "\023\n\017DEVICEDRIVER_P4\020\003\022&\n\"DEVICEDRIVER_IET" +
-      "F_NETWORK_TOPOLOGY\020\004\022\033\n\027DEVICEDRIVER_ONF" +
-      "_TR_352\020\005*\217\001\n\033DeviceOperationalStatusEnu" +
-      "m\022%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\020\000" +
-      "\022$\n DEVICEOPERATIONALSTATUS_DISABLED\020\001\022#" +
-      "\n\037DEVICEOPERATIONALSTATUS_ENABLED\020\002*\201\001\n\017" +
-      "ServiceTypeEnum\022\027\n\023SERVICETYPE_UNKNOWN\020\000" +
-      "\022\024\n\020SERVICETYPE_L3NM\020\001\022\024\n\020SERVICETYPE_L2" +
-      "NM\020\002\022)\n%SERVICETYPE_TAPI_CONNECTIVITY_SE" +
-      "RVICE\020\003*\210\001\n\021ServiceStatusEnum\022\033\n\027SERVICE" +
-      "STATUS_UNDEFINED\020\000\022\031\n\025SERVICESTATUS_PLAN" +
-      "NED\020\001\022\030\n\024SERVICESTATUS_ACTIVE\020\002\022!\n\035SERVI" +
-      "CESTATUS_PENDING_REMOVAL\020\003*]\n\020ConfigActi" +
-      "onEnum\022\032\n\026CONFIGACTION_UNDEFINED\020\000\022\024\n\020CO" +
-      "NFIGACTION_SET\020\001\022\027\n\023CONFIGACTION_DELETE\020" +
-      "\0022\255\020\n\016ContextService\022:\n\016ListContextIds\022\016" +
-      ".context.Empty\032\026.context.ContextIdList\"\000" +
-      "\0226\n\014ListContexts\022\016.context.Empty\032\024.conte" +
-      "xt.ContextList\"\000\0224\n\nGetContext\022\022.context" +
-      ".ContextId\032\020.context.Context\"\000\0224\n\nSetCon" +
-      "text\022\020.context.Context\032\022.context.Context" +
-      "Id\"\000\0225\n\rRemoveContext\022\022.context.ContextI" +
-      "d\032\016.context.Empty\"\000\022=\n\020GetContextEvents\022" +
-      "\016.context.Empty\032\025.context.ContextEvent\"\000" +
-      "0\001\022@\n\017ListTopologyIds\022\022.context.ContextI" +
-      "d\032\027.context.TopologyIdList\"\000\022=\n\016ListTopo" +
-      "logies\022\022.context.ContextId\032\025.context.Top" +
-      "ologyList\"\000\0227\n\013GetTopology\022\023.context.Top" +
-      "ologyId\032\021.context.Topology\"\000\0227\n\013SetTopol" +
-      "ogy\022\021.context.Topology\032\023.context.Topolog" +
-      "yId\"\000\0227\n\016RemoveTopology\022\023.context.Topolo" +
-      "gyId\032\016.context.Empty\"\000\022?\n\021GetTopologyEve" +
-      "nts\022\016.context.Empty\032\026.context.TopologyEv" +
-      "ent\"\0000\001\0228\n\rListDeviceIds\022\016.context.Empty" +
-      "\032\025.context.DeviceIdList\"\000\0224\n\013ListDevices" +
-      "\022\016.context.Empty\032\023.context.DeviceList\"\000\022" +
-      "1\n\tGetDevice\022\021.context.DeviceId\032\017.contex" +
-      "t.Device\"\000\0221\n\tSetDevice\022\017.context.Device" +
-      "\032\021.context.DeviceId\"\000\0223\n\014RemoveDevice\022\021." +
-      "context.DeviceId\032\016.context.Empty\"\000\022;\n\017Ge" +
-      "tDeviceEvents\022\016.context.Empty\032\024.context." +
-      "DeviceEvent\"\0000\001\0224\n\013ListLinkIds\022\016.context" +
-      ".Empty\032\023.context.LinkIdList\"\000\0220\n\tListLin" +
-      "ks\022\016.context.Empty\032\021.context.LinkList\"\000\022" +
-      "+\n\007GetLink\022\017.context.LinkId\032\r.context.Li" +
-      "nk\"\000\022+\n\007SetLink\022\r.context.Link\032\017.context" +
-      ".LinkId\"\000\022/\n\nRemoveLink\022\017.context.LinkId" +
-      "\032\016.context.Empty\"\000\0227\n\rGetLinkEvents\022\016.co" +
-      "ntext.Empty\032\022.context.LinkEvent\"\0000\001\022>\n\016L" +
-      "istServiceIds\022\022.context.ContextId\032\026.cont" +
-      "ext.ServiceIdList\"\000\022:\n\014ListServices\022\022.co" +
-      "ntext.ContextId\032\024.context.ServiceList\"\000\022" +
-      "4\n\nGetService\022\022.context.ServiceId\032\020.cont" +
-      "ext.Service\"\000\0224\n\nSetService\022\020.context.Se" +
-      "rvice\032\022.context.ServiceId\"\000\0225\n\rRemoveSer" +
-      "vice\022\022.context.ServiceId\032\016.context.Empty" +
-      "\"\000\022=\n\020GetServiceEvents\022\016.context.Empty\032\025" +
-      ".context.ServiceEvent\"\0000\001\022D\n\021ListConnect" +
-      "ionIds\022\022.context.ServiceId\032\031.context.Con" +
-      "nectionIdList\"\000\022@\n\017ListConnections\022\022.con" +
-      "text.ServiceId\032\027.context.ConnectionList\"" +
-      "\000\022=\n\rGetConnection\022\025.context.ConnectionI" +
-      "d\032\023.context.Connection\"\000\022=\n\rSetConnectio" +
-      "n\022\023.context.Connection\032\025.context.Connect" +
-      "ionId\"\000\022;\n\020RemoveConnection\022\025.context.Co" +
-      "nnectionId\032\016.context.Empty\"\000\022C\n\023GetConne" +
-      "ctionEvents\022\016.context.Empty\032\030.context.Co" +
-      "nnectionEvent\"\0000\001b\006proto3"
+      "Id\"T\n\007SliceId\022&\n\ncontext_id\030\001 \001(\0132\022.cont" +
+      "ext.ContextId\022!\n\nslice_uuid\030\002 \001(\0132\r.cont" +
+      "ext.Uuid\"\225\002\n\005Slice\022\"\n\010slice_id\030\001 \001(\0132\020.c" +
+      "ontext.SliceId\022/\n\022slice_endpoint_ids\030\002 \003" +
+      "(\0132\023.context.EndPointId\022.\n\021slice_constra" +
+      "ints\030\003 \003(\0132\023.context.Constraint\022-\n\021slice" +
+      "_service_ids\030\004 \003(\0132\022.context.ServiceId\022," +
+      "\n\022slice_subslice_ids\030\005 \003(\0132\020.context.Sli" +
+      "ceId\022*\n\014slice_status\030\006 \001(\0132\024.context.Sli" +
+      "ceStatus\"=\n\013SliceStatus\022.\n\014slice_status\030" +
+      "\001 \001(\0162\030.context.SliceStatusEnum\"2\n\013Slice" +
+      "IdList\022#\n\tslice_ids\030\001 \003(\0132\020.context.Slic" +
+      "eId\"+\n\tSliceList\022\036\n\006slices\030\001 \003(\0132\016.conte" +
+      "xt.Slice\"O\n\nSliceEvent\022\035\n\005event\030\001 \001(\0132\016." +
+      "context.Event\022\"\n\010slice_id\030\002 \001(\0132\020.contex" +
+      "t.SliceId\"6\n\014ConnectionId\022&\n\017connection_" +
+      "uuid\030\001 \001(\0132\r.context.Uuid\"\304\001\n\nConnection" +
+      "\022,\n\rconnection_id\030\001 \001(\0132\025.context.Connec" +
+      "tionId\022&\n\nservice_id\030\002 \001(\0132\022.context.Ser" +
+      "viceId\0223\n\026path_hops_endpoint_ids\030\003 \003(\0132\023" +
+      ".context.EndPointId\022+\n\017sub_service_ids\030\004" +
+      " \003(\0132\022.context.ServiceId\"A\n\020ConnectionId" +
+      "List\022-\n\016connection_ids\030\001 \003(\0132\025.context.C" +
+      "onnectionId\":\n\016ConnectionList\022(\n\013connect" +
+      "ions\030\001 \003(\0132\023.context.Connection\"^\n\017Conne" +
+      "ctionEvent\022\035\n\005event\030\001 \001(\0132\016.context.Even" +
+      "t\022,\n\rconnection_id\030\002 \001(\0132\025.context.Conne" +
+      "ctionId\"\202\001\n\nEndPointId\022(\n\013topology_id\030\001 " +
+      "\001(\0132\023.context.TopologyId\022$\n\tdevice_id\030\002 " +
+      "\001(\0132\021.context.DeviceId\022$\n\rendpoint_uuid\030" +
+      "\003 \001(\0132\r.context.Uuid\"\206\001\n\010EndPoint\022(\n\013end" +
+      "point_id\030\001 \001(\0132\023.context.EndPointId\022\025\n\re" +
+      "ndpoint_type\030\002 \001(\t\0229\n\020kpi_sample_types\030\003" +
+      " \003(\0162\037.kpi_sample_types.KpiSampleType\"e\n" +
+      "\nConfigRule\022)\n\006action\030\001 \001(\0162\031.context.Co" +
+      "nfigActionEnum\022\024\n\014resource_key\030\002 \001(\t\022\026\n\016" +
+      "resource_value\030\003 \001(\t\"?\n\nConstraint\022\027\n\017co" +
+      "nstraint_type\030\001 \001(\t\022\030\n\020constraint_value\030" +
+      "\002 \001(\t\"^\n\022TeraFlowController\022&\n\ncontext_i" +
+      "d\030\001 \001(\0132\022.context.ContextId\022\022\n\nip_addres" +
+      "s\030\002 \001(\t\022\014\n\004port\030\003 \001(\r\"U\n\024AuthenticationR" +
+      "esult\022&\n\ncontext_id\030\001 \001(\0132\022.context.Cont" +
+      "extId\022\025\n\rauthenticated\030\002 \001(\010*j\n\rEventTyp" +
+      "eEnum\022\027\n\023EVENTTYPE_UNDEFINED\020\000\022\024\n\020EVENTT" +
+      "YPE_CREATE\020\001\022\024\n\020EVENTTYPE_UPDATE\020\002\022\024\n\020EV" +
+      "ENTTYPE_REMOVE\020\003*\305\001\n\020DeviceDriverEnum\022\032\n" +
+      "\026DEVICEDRIVER_UNDEFINED\020\000\022\033\n\027DEVICEDRIVE" +
+      "R_OPENCONFIG\020\001\022\036\n\032DEVICEDRIVER_TRANSPORT" +
+      "_API\020\002\022\023\n\017DEVICEDRIVER_P4\020\003\022&\n\"DEVICEDRI" +
+      "VER_IETF_NETWORK_TOPOLOGY\020\004\022\033\n\027DEVICEDRI" +
+      "VER_ONF_TR_352\020\005*\217\001\n\033DeviceOperationalSt" +
+      "atusEnum\022%\n!DEVICEOPERATIONALSTATUS_UNDE" +
+      "FINED\020\000\022$\n DEVICEOPERATIONALSTATUS_DISAB" +
+      "LED\020\001\022#\n\037DEVICEOPERATIONALSTATUS_ENABLED" +
+      "\020\002*\201\001\n\017ServiceTypeEnum\022\027\n\023SERVICETYPE_UN" +
+      "KNOWN\020\000\022\024\n\020SERVICETYPE_L3NM\020\001\022\024\n\020SERVICE" +
+      "TYPE_L2NM\020\002\022)\n%SERVICETYPE_TAPI_CONNECTI" +
+      "VITY_SERVICE\020\003*\210\001\n\021ServiceStatusEnum\022\033\n\027" +
+      "SERVICESTATUS_UNDEFINED\020\000\022\031\n\025SERVICESTAT" +
+      "US_PLANNED\020\001\022\030\n\024SERVICESTATUS_ACTIVE\020\002\022!" +
+      "\n\035SERVICESTATUS_PENDING_REMOVAL\020\003*\213\001\n\017Sl" +
+      "iceStatusEnum\022\031\n\025SLICESTATUS_UNDEFINED\020\000" +
+      "\022\027\n\023SLICESTATUS_PLANNED\020\001\022\024\n\020SLICESTATUS" +
+      "_INIT\020\002\022\026\n\022SLICESTATUS_ACTIVE\020\003\022\026\n\022SLICE" +
+      "STATUS_DEINIT\020\004*]\n\020ConfigActionEnum\022\032\n\026C" +
+      "ONFIGACTION_UNDEFINED\020\000\022\024\n\020CONFIGACTION_" +
+      "SET\020\001\022\027\n\023CONFIGACTION_DELETE\020\0022\357\022\n\016Conte" +
+      "xtService\022:\n\016ListContextIds\022\016.context.Em" +
+      "pty\032\026.context.ContextIdList\"\000\0226\n\014ListCon" +
+      "texts\022\016.context.Empty\032\024.context.ContextL" +
+      "ist\"\000\0224\n\nGetContext\022\022.context.ContextId\032" +
+      "\020.context.Context\"\000\0224\n\nSetContext\022\020.cont" +
+      "ext.Context\032\022.context.ContextId\"\000\0225\n\rRem" +
+      "oveContext\022\022.context.ContextId\032\016.context" +
+      ".Empty\"\000\022=\n\020GetContextEvents\022\016.context.E" +
+      "mpty\032\025.context.ContextEvent\"\0000\001\022@\n\017ListT" +
+      "opologyIds\022\022.context.ContextId\032\027.context" +
+      ".TopologyIdList\"\000\022=\n\016ListTopologies\022\022.co" +
+      "ntext.ContextId\032\025.context.TopologyList\"\000" +
+      "\0227\n\013GetTopology\022\023.context.TopologyId\032\021.c" +
+      "ontext.Topology\"\000\0227\n\013SetTopology\022\021.conte" +
+      "xt.Topology\032\023.context.TopologyId\"\000\0227\n\016Re" +
+      "moveTopology\022\023.context.TopologyId\032\016.cont" +
+      "ext.Empty\"\000\022?\n\021GetTopologyEvents\022\016.conte" +
+      "xt.Empty\032\026.context.TopologyEvent\"\0000\001\0228\n\r" +
+      "ListDeviceIds\022\016.context.Empty\032\025.context." +
+      "DeviceIdList\"\000\0224\n\013ListDevices\022\016.context." +
+      "Empty\032\023.context.DeviceList\"\000\0221\n\tGetDevic" +
+      "e\022\021.context.DeviceId\032\017.context.Device\"\000\022" +
+      "1\n\tSetDevice\022\017.context.Device\032\021.context." +
+      "DeviceId\"\000\0223\n\014RemoveDevice\022\021.context.Dev" +
+      "iceId\032\016.context.Empty\"\000\022;\n\017GetDeviceEven" +
+      "ts\022\016.context.Empty\032\024.context.DeviceEvent" +
+      "\"\0000\001\0224\n\013ListLinkIds\022\016.context.Empty\032\023.co" +
+      "ntext.LinkIdList\"\000\0220\n\tListLinks\022\016.contex" +
+      "t.Empty\032\021.context.LinkList\"\000\022+\n\007GetLink\022" +
+      "\017.context.LinkId\032\r.context.Link\"\000\022+\n\007Set" +
+      "Link\022\r.context.Link\032\017.context.LinkId\"\000\022/" +
+      "\n\nRemoveLink\022\017.context.LinkId\032\016.context." +
+      "Empty\"\000\0227\n\rGetLinkEvents\022\016.context.Empty" +
+      "\032\022.context.LinkEvent\"\0000\001\022>\n\016ListServiceI" +
+      "ds\022\022.context.ContextId\032\026.context.Service" +
+      "IdList\"\000\022:\n\014ListServices\022\022.context.Conte" +
+      "xtId\032\024.context.ServiceList\"\000\0224\n\nGetServi" +
+      "ce\022\022.context.ServiceId\032\020.context.Service" +
+      "\"\000\0224\n\nSetService\022\020.context.Service\032\022.con" +
+      "text.ServiceId\"\000\0225\n\rRemoveService\022\022.cont" +
+      "ext.ServiceId\032\016.context.Empty\"\000\022=\n\020GetSe" +
+      "rviceEvents\022\016.context.Empty\032\025.context.Se" +
+      "rviceEvent\"\0000\001\022:\n\014ListSliceIds\022\022.context" +
+      ".ContextId\032\024.context.SliceIdList\"\000\0226\n\nLi" +
+      "stSlices\022\022.context.ContextId\032\022.context.S" +
+      "liceList\"\000\022.\n\010GetSlice\022\020.context.SliceId" +
+      "\032\016.context.Slice\"\000\022.\n\010SetSlice\022\016.context" +
+      ".Slice\032\020.context.SliceId\"\000\0221\n\013RemoveSlic" +
+      "e\022\020.context.SliceId\032\016.context.Empty\"\000\0229\n" +
+      "\016GetSliceEvents\022\016.context.Empty\032\023.contex" +
+      "t.SliceEvent\"\0000\001\022D\n\021ListConnectionIds\022\022." +
+      "context.ServiceId\032\031.context.ConnectionId" +
+      "List\"\000\022@\n\017ListConnections\022\022.context.Serv" +
+      "iceId\032\027.context.ConnectionList\"\000\022=\n\rGetC" +
+      "onnection\022\025.context.ConnectionId\032\023.conte" +
+      "xt.Connection\"\000\022=\n\rSetConnection\022\023.conte" +
+      "xt.Connection\032\025.context.ConnectionId\"\000\022;" +
+      "\n\020RemoveConnection\022\025.context.ConnectionI" +
+      "d\032\016.context.Empty\"\000\022C\n\023GetConnectionEven" +
+      "ts\022\016.context.Empty\032\030.context.ConnectionE" +
+      "vent\"\0000\001b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -38037,68 +44311,104 @@ public final class ContextOuterClass {
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ServiceEvent_descriptor,
         new java.lang.String[] { "Event", "ServiceId", });
-    internal_static_context_ConnectionId_descriptor =
+    internal_static_context_SliceId_descriptor =
       getDescriptor().getMessageTypes().get(31);
+    internal_static_context_SliceId_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceId_descriptor,
+        new java.lang.String[] { "ContextId", "SliceUuid", });
+    internal_static_context_Slice_descriptor =
+      getDescriptor().getMessageTypes().get(32);
+    internal_static_context_Slice_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_Slice_descriptor,
+        new java.lang.String[] { "SliceId", "SliceEndpointIds", "SliceConstraints", "SliceServiceIds", "SliceSubsliceIds", "SliceStatus", });
+    internal_static_context_SliceStatus_descriptor =
+      getDescriptor().getMessageTypes().get(33);
+    internal_static_context_SliceStatus_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceStatus_descriptor,
+        new java.lang.String[] { "SliceStatus", });
+    internal_static_context_SliceIdList_descriptor =
+      getDescriptor().getMessageTypes().get(34);
+    internal_static_context_SliceIdList_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceIdList_descriptor,
+        new java.lang.String[] { "SliceIds", });
+    internal_static_context_SliceList_descriptor =
+      getDescriptor().getMessageTypes().get(35);
+    internal_static_context_SliceList_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceList_descriptor,
+        new java.lang.String[] { "Slices", });
+    internal_static_context_SliceEvent_descriptor =
+      getDescriptor().getMessageTypes().get(36);
+    internal_static_context_SliceEvent_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_context_SliceEvent_descriptor,
+        new java.lang.String[] { "Event", "SliceId", });
+    internal_static_context_ConnectionId_descriptor =
+      getDescriptor().getMessageTypes().get(37);
     internal_static_context_ConnectionId_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConnectionId_descriptor,
         new java.lang.String[] { "ConnectionUuid", });
     internal_static_context_Connection_descriptor =
-      getDescriptor().getMessageTypes().get(32);
+      getDescriptor().getMessageTypes().get(38);
     internal_static_context_Connection_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_Connection_descriptor,
         new java.lang.String[] { "ConnectionId", "ServiceId", "PathHopsEndpointIds", "SubServiceIds", });
     internal_static_context_ConnectionIdList_descriptor =
-      getDescriptor().getMessageTypes().get(33);
+      getDescriptor().getMessageTypes().get(39);
     internal_static_context_ConnectionIdList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConnectionIdList_descriptor,
         new java.lang.String[] { "ConnectionIds", });
     internal_static_context_ConnectionList_descriptor =
-      getDescriptor().getMessageTypes().get(34);
+      getDescriptor().getMessageTypes().get(40);
     internal_static_context_ConnectionList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConnectionList_descriptor,
         new java.lang.String[] { "Connections", });
     internal_static_context_ConnectionEvent_descriptor =
-      getDescriptor().getMessageTypes().get(35);
+      getDescriptor().getMessageTypes().get(41);
     internal_static_context_ConnectionEvent_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConnectionEvent_descriptor,
         new java.lang.String[] { "Event", "ConnectionId", });
     internal_static_context_EndPointId_descriptor =
-      getDescriptor().getMessageTypes().get(36);
+      getDescriptor().getMessageTypes().get(42);
     internal_static_context_EndPointId_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_EndPointId_descriptor,
         new java.lang.String[] { "TopologyId", "DeviceId", "EndpointUuid", });
     internal_static_context_EndPoint_descriptor =
-      getDescriptor().getMessageTypes().get(37);
+      getDescriptor().getMessageTypes().get(43);
     internal_static_context_EndPoint_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_EndPoint_descriptor,
         new java.lang.String[] { "EndpointId", "EndpointType", "KpiSampleTypes", });
     internal_static_context_ConfigRule_descriptor =
-      getDescriptor().getMessageTypes().get(38);
+      getDescriptor().getMessageTypes().get(44);
     internal_static_context_ConfigRule_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_ConfigRule_descriptor,
         new java.lang.String[] { "Action", "ResourceKey", "ResourceValue", });
     internal_static_context_Constraint_descriptor =
-      getDescriptor().getMessageTypes().get(39);
+      getDescriptor().getMessageTypes().get(45);
     internal_static_context_Constraint_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_Constraint_descriptor,
         new java.lang.String[] { "ConstraintType", "ConstraintValue", });
     internal_static_context_TeraFlowController_descriptor =
-      getDescriptor().getMessageTypes().get(40);
+      getDescriptor().getMessageTypes().get(46);
     internal_static_context_TeraFlowController_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_TeraFlowController_descriptor,
         new java.lang.String[] { "ContextId", "IpAddress", "Port", });
     internal_static_context_AuthenticationResult_descriptor =
-      getDescriptor().getMessageTypes().get(41);
+      getDescriptor().getMessageTypes().get(47);
     internal_static_context_AuthenticationResult_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_context_AuthenticationResult_descriptor,
diff --git a/src/automation/target/generated-sources/grpc/context/ContextService.java b/src/automation/target/generated-sources/grpc/context/ContextService.java
index cbd51163f..d54c56057 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextService.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextService.java
@@ -58,6 +58,16 @@ public interface ContextService extends MutinyService {
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeService(context.ContextOuterClass.ServiceId request);
     
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request);
+    
     io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request);
     
     io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionList> listConnections(context.ContextOuterClass.ServiceId request);
@@ -79,6 +89,8 @@ public interface ContextService extends MutinyService {
     
     io.smallrye.mutiny.Multi<context.ContextOuterClass.ServiceEvent> getServiceEvents(context.ContextOuterClass.Empty request);
     
+    io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request);
+    
     io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request);
     
     
diff --git a/src/automation/target/generated-sources/grpc/context/ContextServiceBean.java b/src/automation/target/generated-sources/grpc/context/ContextServiceBean.java
index 6900cf3c8..f552294b8 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextServiceBean.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextServiceBean.java
@@ -216,6 +216,46 @@ public class ContextServiceBean extends MutinyContextServiceGrpc.ContextServiceI
        }
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request) {
+       try {
+         return delegate.listSliceIds(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request) {
+       try {
+         return delegate.listSlices(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request) {
+       try {
+         return delegate.getSlice(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request) {
+       try {
+         return delegate.setSlice(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
+       try {
+         return delegate.removeSlice(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request) {
        try {
          return delegate.listConnectionIds(request);
@@ -301,6 +341,15 @@ public class ContextServiceBean extends MutinyContextServiceGrpc.ContextServiceI
        }
     }
 
+    @Override
+    public io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request) {
+       try {
+         return delegate.getSliceEvents(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+
     @Override
     public io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request) {
        try {
diff --git a/src/automation/target/generated-sources/grpc/context/ContextServiceClient.java b/src/automation/target/generated-sources/grpc/context/ContextServiceClient.java
index a3d74cb7d..c6493bd4d 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextServiceClient.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextServiceClient.java
@@ -121,6 +121,26 @@ public class ContextServiceClient implements ContextService, MutinyClient<Mutiny
        return stub.removeService(request);
     }
     @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request) {
+       return stub.listSliceIds(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request) {
+       return stub.listSlices(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request) {
+       return stub.getSlice(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request) {
+       return stub.setSlice(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
+       return stub.removeSlice(request);
+    }
+    @Override
     public io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request) {
        return stub.listConnectionIds(request);
     }
@@ -166,6 +186,11 @@ public class ContextServiceClient implements ContextService, MutinyClient<Mutiny
        return stub.getServiceEvents(request);
     }
 
+    @Override
+    public io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request) {
+       return stub.getSliceEvents(request);
+    }
+
     @Override
     public io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request) {
        return stub.getConnectionEvents(request);
diff --git a/src/automation/target/generated-sources/grpc/context/ContextServiceGrpc.java b/src/automation/target/generated-sources/grpc/context/ContextServiceGrpc.java
index be9f381ff..be720c127 100644
--- a/src/automation/target/generated-sources/grpc/context/ContextServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/context/ContextServiceGrpc.java
@@ -944,6 +944,192 @@ public final class ContextServiceGrpc {
     return getGetServiceEventsMethod;
   }
 
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId,
+      context.ContextOuterClass.SliceIdList> getListSliceIdsMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "ListSliceIds",
+      requestType = context.ContextOuterClass.ContextId.class,
+      responseType = context.ContextOuterClass.SliceIdList.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId,
+      context.ContextOuterClass.SliceIdList> getListSliceIdsMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId, context.ContextOuterClass.SliceIdList> getListSliceIdsMethod;
+    if ((getListSliceIdsMethod = ContextServiceGrpc.getListSliceIdsMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getListSliceIdsMethod = ContextServiceGrpc.getListSliceIdsMethod) == null) {
+          ContextServiceGrpc.getListSliceIdsMethod = getListSliceIdsMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.ContextId, context.ContextOuterClass.SliceIdList>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ListSliceIds"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.ContextId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceIdList.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("ListSliceIds"))
+              .build();
+        }
+      }
+    }
+    return getListSliceIdsMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId,
+      context.ContextOuterClass.SliceList> getListSlicesMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "ListSlices",
+      requestType = context.ContextOuterClass.ContextId.class,
+      responseType = context.ContextOuterClass.SliceList.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId,
+      context.ContextOuterClass.SliceList> getListSlicesMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.ContextId, context.ContextOuterClass.SliceList> getListSlicesMethod;
+    if ((getListSlicesMethod = ContextServiceGrpc.getListSlicesMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getListSlicesMethod = ContextServiceGrpc.getListSlicesMethod) == null) {
+          ContextServiceGrpc.getListSlicesMethod = getListSlicesMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.ContextId, context.ContextOuterClass.SliceList>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "ListSlices"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.ContextId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceList.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("ListSlices"))
+              .build();
+        }
+      }
+    }
+    return getListSlicesMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
+      context.ContextOuterClass.Slice> getGetSliceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "GetSlice",
+      requestType = context.ContextOuterClass.SliceId.class,
+      responseType = context.ContextOuterClass.Slice.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
+      context.ContextOuterClass.Slice> getGetSliceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId, context.ContextOuterClass.Slice> getGetSliceMethod;
+    if ((getGetSliceMethod = ContextServiceGrpc.getGetSliceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getGetSliceMethod = ContextServiceGrpc.getGetSliceMethod) == null) {
+          ContextServiceGrpc.getGetSliceMethod = getGetSliceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.SliceId, context.ContextOuterClass.Slice>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetSlice"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Slice.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("GetSlice"))
+              .build();
+        }
+      }
+    }
+    return getGetSliceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Slice,
+      context.ContextOuterClass.SliceId> getSetSliceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "SetSlice",
+      requestType = context.ContextOuterClass.Slice.class,
+      responseType = context.ContextOuterClass.SliceId.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.Slice,
+      context.ContextOuterClass.SliceId> getSetSliceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId> getSetSliceMethod;
+    if ((getSetSliceMethod = ContextServiceGrpc.getSetSliceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getSetSliceMethod = ContextServiceGrpc.getSetSliceMethod) == null) {
+          ContextServiceGrpc.getSetSliceMethod = getSetSliceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Slice, context.ContextOuterClass.SliceId>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "SetSlice"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Slice.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceId.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("SetSlice"))
+              .build();
+        }
+      }
+    }
+    return getSetSliceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
+      context.ContextOuterClass.Empty> getRemoveSliceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "RemoveSlice",
+      requestType = context.ContextOuterClass.SliceId.class,
+      responseType = context.ContextOuterClass.Empty.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId,
+      context.ContextOuterClass.Empty> getRemoveSliceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.SliceId, context.ContextOuterClass.Empty> getRemoveSliceMethod;
+    if ((getRemoveSliceMethod = ContextServiceGrpc.getRemoveSliceMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getRemoveSliceMethod = ContextServiceGrpc.getRemoveSliceMethod) == null) {
+          ContextServiceGrpc.getRemoveSliceMethod = getRemoveSliceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.SliceId, context.ContextOuterClass.Empty>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "RemoveSlice"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Empty.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("RemoveSlice"))
+              .build();
+        }
+      }
+    }
+    return getRemoveSliceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Empty,
+      context.ContextOuterClass.SliceEvent> getGetSliceEventsMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "GetSliceEvents",
+      requestType = context.ContextOuterClass.Empty.class,
+      responseType = context.ContextOuterClass.SliceEvent.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.Empty,
+      context.ContextOuterClass.SliceEvent> getGetSliceEventsMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Empty, context.ContextOuterClass.SliceEvent> getGetSliceEventsMethod;
+    if ((getGetSliceEventsMethod = ContextServiceGrpc.getGetSliceEventsMethod) == null) {
+      synchronized (ContextServiceGrpc.class) {
+        if ((getGetSliceEventsMethod = ContextServiceGrpc.getGetSliceEventsMethod) == null) {
+          ContextServiceGrpc.getGetSliceEventsMethod = getGetSliceEventsMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Empty, context.ContextOuterClass.SliceEvent>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetSliceEvents"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Empty.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.SliceEvent.getDefaultInstance()))
+              .setSchemaDescriptor(new ContextServiceMethodDescriptorSupplier("GetSliceEvents"))
+              .build();
+        }
+      }
+    }
+    return getGetSliceEventsMethod;
+  }
+
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId,
       context.ContextOuterClass.ConnectionIdList> getListConnectionIdsMethod;
 
@@ -1388,6 +1574,48 @@ public final class ContextServiceGrpc {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetServiceEventsMethod(), responseObserver);
     }
 
+    /**
+     */
+    public void listSliceIds(context.ContextOuterClass.ContextId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceIdList> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getListSliceIdsMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void listSlices(context.ContextOuterClass.ContextId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceList> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getListSlicesMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void getSlice(context.ContextOuterClass.SliceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Slice> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetSliceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void setSlice(context.ContextOuterClass.Slice request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getSetSliceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void removeSlice(context.ContextOuterClass.SliceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getRemoveSliceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void getSliceEvents(context.ContextOuterClass.Empty request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceEvent> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetSliceEventsMethod(), responseObserver);
+    }
+
     /**
      */
     public void listConnectionIds(context.ContextOuterClass.ServiceId request,
@@ -1642,6 +1870,48 @@ public final class ContextServiceGrpc {
                 context.ContextOuterClass.Empty,
                 context.ContextOuterClass.ServiceEvent>(
                   this, METHODID_GET_SERVICE_EVENTS)))
+          .addMethod(
+            getListSliceIdsMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.ContextId,
+                context.ContextOuterClass.SliceIdList>(
+                  this, METHODID_LIST_SLICE_IDS)))
+          .addMethod(
+            getListSlicesMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.ContextId,
+                context.ContextOuterClass.SliceList>(
+                  this, METHODID_LIST_SLICES)))
+          .addMethod(
+            getGetSliceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.SliceId,
+                context.ContextOuterClass.Slice>(
+                  this, METHODID_GET_SLICE)))
+          .addMethod(
+            getSetSliceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Slice,
+                context.ContextOuterClass.SliceId>(
+                  this, METHODID_SET_SLICE)))
+          .addMethod(
+            getRemoveSliceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.SliceId,
+                context.ContextOuterClass.Empty>(
+                  this, METHODID_REMOVE_SLICE)))
+          .addMethod(
+            getGetSliceEventsMethod(),
+            io.grpc.stub.ServerCalls.asyncServerStreamingCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Empty,
+                context.ContextOuterClass.SliceEvent>(
+                  this, METHODID_GET_SLICE_EVENTS)))
           .addMethod(
             getListConnectionIdsMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
@@ -1942,6 +2212,54 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getGetServiceEventsMethod(), getCallOptions()), request, responseObserver);
     }
 
+    /**
+     */
+    public void listSliceIds(context.ContextOuterClass.ContextId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceIdList> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getListSliceIdsMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void listSlices(context.ContextOuterClass.ContextId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceList> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getListSlicesMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void getSlice(context.ContextOuterClass.SliceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Slice> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getGetSliceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void setSlice(context.ContextOuterClass.Slice request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getSetSliceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void removeSlice(context.ContextOuterClass.SliceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getRemoveSliceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void getSliceEvents(context.ContextOuterClass.Empty request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceEvent> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncServerStreamingCall(
+          getChannel().newCall(getGetSliceEventsMethod(), getCallOptions()), request, responseObserver);
+    }
+
     /**
      */
     public void listConnectionIds(context.ContextOuterClass.ServiceId request,
@@ -2220,6 +2538,49 @@ public final class ContextServiceGrpc {
           getChannel(), getGetServiceEventsMethod(), getCallOptions(), request);
     }
 
+    /**
+     */
+    public context.ContextOuterClass.SliceIdList listSliceIds(context.ContextOuterClass.ContextId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getListSliceIdsMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.SliceList listSlices(context.ContextOuterClass.ContextId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getListSlicesMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.Slice getSlice(context.ContextOuterClass.SliceId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getGetSliceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.SliceId setSlice(context.ContextOuterClass.Slice request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getSetSliceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.Empty removeSlice(context.ContextOuterClass.SliceId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getRemoveSliceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public java.util.Iterator<context.ContextOuterClass.SliceEvent> getSliceEvents(
+        context.ContextOuterClass.Empty request) {
+      return io.grpc.stub.ClientCalls.blockingServerStreamingCall(
+          getChannel(), getGetSliceEventsMethod(), getCallOptions(), request);
+    }
+
     /**
      */
     public context.ContextOuterClass.ConnectionIdList listConnectionIds(context.ContextOuterClass.ServiceId request) {
@@ -2478,6 +2839,46 @@ public final class ContextServiceGrpc {
           getChannel().newCall(getRemoveServiceMethod(), getCallOptions()), request);
     }
 
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.SliceIdList> listSliceIds(
+        context.ContextOuterClass.ContextId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getListSliceIdsMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.SliceList> listSlices(
+        context.ContextOuterClass.ContextId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getListSlicesMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Slice> getSlice(
+        context.ContextOuterClass.SliceId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getGetSliceMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.SliceId> setSlice(
+        context.ContextOuterClass.Slice request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getSetSliceMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> removeSlice(
+        context.ContextOuterClass.SliceId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getRemoveSliceMethod(), getCallOptions()), request);
+    }
+
     /**
      */
     public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.ConnectionIdList> listConnectionIds(
@@ -2549,12 +2950,18 @@ public final class ContextServiceGrpc {
   private static final int METHODID_SET_SERVICE = 27;
   private static final int METHODID_REMOVE_SERVICE = 28;
   private static final int METHODID_GET_SERVICE_EVENTS = 29;
-  private static final int METHODID_LIST_CONNECTION_IDS = 30;
-  private static final int METHODID_LIST_CONNECTIONS = 31;
-  private static final int METHODID_GET_CONNECTION = 32;
-  private static final int METHODID_SET_CONNECTION = 33;
-  private static final int METHODID_REMOVE_CONNECTION = 34;
-  private static final int METHODID_GET_CONNECTION_EVENTS = 35;
+  private static final int METHODID_LIST_SLICE_IDS = 30;
+  private static final int METHODID_LIST_SLICES = 31;
+  private static final int METHODID_GET_SLICE = 32;
+  private static final int METHODID_SET_SLICE = 33;
+  private static final int METHODID_REMOVE_SLICE = 34;
+  private static final int METHODID_GET_SLICE_EVENTS = 35;
+  private static final int METHODID_LIST_CONNECTION_IDS = 36;
+  private static final int METHODID_LIST_CONNECTIONS = 37;
+  private static final int METHODID_GET_CONNECTION = 38;
+  private static final int METHODID_SET_CONNECTION = 39;
+  private static final int METHODID_REMOVE_CONNECTION = 40;
+  private static final int METHODID_GET_CONNECTION_EVENTS = 41;
 
   private static final class MethodHandlers<Req, Resp> implements
       io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -2693,6 +3100,30 @@ public final class ContextServiceGrpc {
           serviceImpl.getServiceEvents((context.ContextOuterClass.Empty) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceEvent>) responseObserver);
           break;
+        case METHODID_LIST_SLICE_IDS:
+          serviceImpl.listSliceIds((context.ContextOuterClass.ContextId) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceIdList>) responseObserver);
+          break;
+        case METHODID_LIST_SLICES:
+          serviceImpl.listSlices((context.ContextOuterClass.ContextId) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceList>) responseObserver);
+          break;
+        case METHODID_GET_SLICE:
+          serviceImpl.getSlice((context.ContextOuterClass.SliceId) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Slice>) responseObserver);
+          break;
+        case METHODID_SET_SLICE:
+          serviceImpl.setSlice((context.ContextOuterClass.Slice) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver);
+          break;
+        case METHODID_REMOVE_SLICE:
+          serviceImpl.removeSlice((context.ContextOuterClass.SliceId) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
+          break;
+        case METHODID_GET_SLICE_EVENTS:
+          serviceImpl.getSliceEvents((context.ContextOuterClass.Empty) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceEvent>) responseObserver);
+          break;
         case METHODID_LIST_CONNECTION_IDS:
           serviceImpl.listConnectionIds((context.ContextOuterClass.ServiceId) request,
               (io.grpc.stub.StreamObserver<context.ContextOuterClass.ConnectionIdList>) responseObserver);
@@ -2808,6 +3239,12 @@ public final class ContextServiceGrpc {
               .addMethod(getSetServiceMethod())
               .addMethod(getRemoveServiceMethod())
               .addMethod(getGetServiceEventsMethod())
+              .addMethod(getListSliceIdsMethod())
+              .addMethod(getListSlicesMethod())
+              .addMethod(getGetSliceMethod())
+              .addMethod(getSetSliceMethod())
+              .addMethod(getRemoveSliceMethod())
+              .addMethod(getGetSliceEventsMethod())
               .addMethod(getListConnectionIdsMethod())
               .addMethod(getListConnectionsMethod())
               .addMethod(getGetConnectionMethod())
diff --git a/src/automation/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java b/src/automation/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
index 85abba20a..9f71b5378 100644
--- a/src/automation/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
+++ b/src/automation/target/generated-sources/grpc/context/MutinyContextServiceGrpc.java
@@ -161,6 +161,31 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::listSliceIds);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::listSlices);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getSlice);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::setSlice);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::removeSlice);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::listConnectionIds);
         }
@@ -211,6 +236,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::getSliceEvents);
+        }
+
+        
         public io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::getConnectionEvents);
         }
@@ -358,6 +388,31 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceIdList> listSliceIds(context.ContextOuterClass.ContextId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceList> listSlices(context.ContextOuterClass.ContextId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Slice> getSlice(context.ContextOuterClass.SliceId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.SliceId> setSlice(context.ContextOuterClass.Slice request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> removeSlice(context.ContextOuterClass.SliceId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
         public io.smallrye.mutiny.Uni<context.ContextOuterClass.ConnectionIdList> listConnectionIds(context.ContextOuterClass.ServiceId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
@@ -408,6 +463,11 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
         }
 
         
+        public io.smallrye.mutiny.Multi<context.ContextOuterClass.SliceEvent> getSliceEvents(context.ContextOuterClass.Empty request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
         public io.smallrye.mutiny.Multi<context.ContextOuterClass.ConnectionEvent> getConnectionEvents(context.ContextOuterClass.Empty request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
@@ -624,6 +684,48 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                                             context.ContextOuterClass.Empty,
                                             context.ContextOuterClass.ServiceEvent>(
                                             this, METHODID_GET_SERVICE_EVENTS, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getListSliceIdsMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.ContextId,
+                                            context.ContextOuterClass.SliceIdList>(
+                                            this, METHODID_LIST_SLICE_IDS, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getListSlicesMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.ContextId,
+                                            context.ContextOuterClass.SliceList>(
+                                            this, METHODID_LIST_SLICES, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getGetSliceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.SliceId,
+                                            context.ContextOuterClass.Slice>(
+                                            this, METHODID_GET_SLICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getSetSliceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Slice,
+                                            context.ContextOuterClass.SliceId>(
+                                            this, METHODID_SET_SLICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getRemoveSliceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.SliceId,
+                                            context.ContextOuterClass.Empty>(
+                                            this, METHODID_REMOVE_SLICE, compression)))
+                    .addMethod(
+                            context.ContextServiceGrpc.getGetSliceEventsMethod(),
+                            asyncServerStreamingCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Empty,
+                                            context.ContextOuterClass.SliceEvent>(
+                                            this, METHODID_GET_SLICE_EVENTS, compression)))
                     .addMethod(
                             context.ContextServiceGrpc.getListConnectionIdsMethod(),
                             asyncUnaryCall(
@@ -700,12 +802,18 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
     private static final int METHODID_SET_SERVICE = 27;
     private static final int METHODID_REMOVE_SERVICE = 28;
     private static final int METHODID_GET_SERVICE_EVENTS = 29;
-    private static final int METHODID_LIST_CONNECTION_IDS = 30;
-    private static final int METHODID_LIST_CONNECTIONS = 31;
-    private static final int METHODID_GET_CONNECTION = 32;
-    private static final int METHODID_SET_CONNECTION = 33;
-    private static final int METHODID_REMOVE_CONNECTION = 34;
-    private static final int METHODID_GET_CONNECTION_EVENTS = 35;
+    private static final int METHODID_LIST_SLICE_IDS = 30;
+    private static final int METHODID_LIST_SLICES = 31;
+    private static final int METHODID_GET_SLICE = 32;
+    private static final int METHODID_SET_SLICE = 33;
+    private static final int METHODID_REMOVE_SLICE = 34;
+    private static final int METHODID_GET_SLICE_EVENTS = 35;
+    private static final int METHODID_LIST_CONNECTION_IDS = 36;
+    private static final int METHODID_LIST_CONNECTIONS = 37;
+    private static final int METHODID_GET_CONNECTION = 38;
+    private static final int METHODID_SET_CONNECTION = 39;
+    private static final int METHODID_REMOVE_CONNECTION = 40;
+    private static final int METHODID_GET_CONNECTION_EVENTS = 41;
 
     private static final class MethodHandlers<Req, Resp> implements
             io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -906,6 +1014,42 @@ public final class MutinyContextServiceGrpc implements io.quarkus.grpc.runtime.M
                             compression,
                             serviceImpl::getServiceEvents);
                     break;
+                case METHODID_LIST_SLICE_IDS:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ContextId) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceIdList>) responseObserver,
+                            compression,
+                            serviceImpl::listSliceIds);
+                    break;
+                case METHODID_LIST_SLICES:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ContextId) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceList>) responseObserver,
+                            compression,
+                            serviceImpl::listSlices);
+                    break;
+                case METHODID_GET_SLICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.SliceId) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Slice>) responseObserver,
+                            compression,
+                            serviceImpl::getSlice);
+                    break;
+                case METHODID_SET_SLICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Slice) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceId>) responseObserver,
+                            compression,
+                            serviceImpl::setSlice);
+                    break;
+                case METHODID_REMOVE_SLICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.SliceId) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
+                            compression,
+                            serviceImpl::removeSlice);
+                    break;
+                case METHODID_GET_SLICE_EVENTS:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToMany((context.ContextOuterClass.Empty) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.SliceEvent>) responseObserver,
+                            compression,
+                            serviceImpl::getSliceEvents);
+                    break;
                 case METHODID_LIST_CONNECTION_IDS:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ServiceId) request,
                             (io.grpc.stub.StreamObserver<context.ContextOuterClass.ConnectionIdList>) responseObserver,
diff --git a/src/automation/target/kubernetes/kubernetes.yml b/src/automation/target/kubernetes/kubernetes.yml
index d8d4dc544..0e4bc0c62 100644
--- a/src/automation/target/kubernetes/kubernetes.yml
+++ b/src/automation/target/kubernetes/kubernetes.yml
@@ -1,36 +1,22 @@
-# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#      http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
 ---
 apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 644f8ea4385acb720eab7317de057f9d1d8ebfe6
-    app.quarkus.io/build-timestamp: 2022-02-14 - 10:21:58 +0000
+    app.quarkus.io/commit-id: fee580ca578000e6006c77704c0d6240e261de0f
+    app.quarkus.io/build-timestamp: 2022-05-27 - 08:02:36 +0000
   labels:
     app.kubernetes.io/name: automationservice
     app: automationservice
   name: automationservice
 spec:
   ports:
-    - name: http
-      port: 8080
-      targetPort: 8080
     - name: grpc-server
       port: 9999
       targetPort: 9999
+    - name: http
+      port: 8080
+      targetPort: 8080
   selector:
     app.kubernetes.io/name: automationservice
   type: ClusterIP
@@ -39,8 +25,8 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 644f8ea4385acb720eab7317de057f9d1d8ebfe6
-    app.quarkus.io/build-timestamp: 2022-02-14 - 10:21:58 +0000
+    app.quarkus.io/commit-id: fee580ca578000e6006c77704c0d6240e261de0f
+    app.quarkus.io/build-timestamp: 2022-05-27 - 08:02:36 +0000
   labels:
     app: automationservice
     app.kubernetes.io/name: automationservice
@@ -53,8 +39,8 @@ spec:
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: 644f8ea4385acb720eab7317de057f9d1d8ebfe6
-        app.quarkus.io/build-timestamp: 2022-02-14 - 10:21:58 +0000
+        app.quarkus.io/commit-id: fee580ca578000e6006c77704c0d6240e261de0f
+        app.quarkus.io/build-timestamp: 2022-05-27 - 08:02:36 +0000
       labels:
         app: automationservice
         app.kubernetes.io/name: automationservice
@@ -65,10 +51,10 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
-            - name: DEVICE_SERVICE_HOST
-              value: deviceservice
             - name: CONTEXT_SERVICE_HOST
-              value: contextservice
+              value: ContextService
+            - name: DEVICE_SERVICE_HOST
+              value: DeviceService
           image: registry.gitlab.com/teraflow-h2020/controller/automation:0.2.0
           imagePullPolicy: Always
           livenessProbe:
@@ -83,12 +69,12 @@ spec:
             timeoutSeconds: 10
           name: automationservice
           ports:
-            - containerPort: 8080
-              name: http
-              protocol: TCP
             - containerPort: 9999
               name: grpc-server
               protocol: TCP
+            - containerPort: 8080
+              name: http
+              protocol: TCP
           readinessProbe:
             failureThreshold: 3
             httpGet:
-- 
GitLab


From 08afff093bb97c9905381b440b99a151d14254dd Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Fri, 27 May 2022 11:10:41 +0300
Subject: [PATCH 46/60] test(automation): add contextSubscriberTest

---
 .../AutomationFunctionalServiceTest.java      |  41 ++--
 .../automation/ContextSubscriberTest.java     | 199 ++++++++++++++++++
 .../MockAutomationConfiguration.java          |  18 ++
 3 files changed, 238 insertions(+), 20 deletions(-)
 create mode 100644 src/automation/src/test/java/eu/teraflow/automation/ContextSubscriberTest.java
 create mode 100644 src/automation/src/test/java/eu/teraflow/automation/MockAutomationConfiguration.java

diff --git a/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java b/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java
index f584a86ca..276a74742 100644
--- a/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java
+++ b/src/automation/src/test/java/eu/teraflow/automation/AutomationFunctionalServiceTest.java
@@ -1,18 +1,18 @@
 /*
- * Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
 
 package eu.teraflow.automation;
 
@@ -22,8 +22,11 @@ import automation.Automation;
 import context.ContextOuterClass;
 import eu.teraflow.automation.context.ContextGateway;
 import eu.teraflow.automation.device.DeviceGateway;
-import eu.teraflow.automation.device.model.*;
+import eu.teraflow.automation.device.model.ConfigActionEnum;
+import eu.teraflow.automation.device.model.ConfigRule;
 import eu.teraflow.automation.device.model.Device;
+import eu.teraflow.automation.device.model.DeviceConfig;
+import eu.teraflow.automation.device.model.DeviceOperationalStatus;
 import io.quarkus.test.junit.QuarkusTest;
 import io.quarkus.test.junit.mockito.InjectMock;
 import io.smallrye.mutiny.Uni;
@@ -37,7 +40,7 @@ import org.junit.jupiter.api.Test;
 import org.mockito.Mockito;
 
 @QuarkusTest
-public class AutomationFunctionalServiceTest {
+class AutomationFunctionalServiceTest {
     private static final Logger LOGGER = Logger.getLogger(AutomationFunctionalServiceTest.class);
 
     @Inject AutomationService automationService;
@@ -97,8 +100,7 @@ public class AutomationFunctionalServiceTest {
                         deviceConfig -> {
                             LOGGER.infof("Received response %s", deviceConfig);
 
-                            assertThat(deviceConfig.getDeviceOperationalStatus().toString())
-                                    .isEqualTo(device.getDeviceOperationalStatus().toString());
+                            assertThat(deviceConfig).hasToString(device.getDeviceOperationalStatus().toString());
 
                             assertThat(deviceConfig.getDeviceConfig().toString()).isNotNull();
 
@@ -163,8 +165,7 @@ public class AutomationFunctionalServiceTest {
                         deviceConfig -> {
                             LOGGER.infof("Received response %s", deviceConfig);
 
-                            assertThat(deviceConfig.getDeviceOperationalStatus().toString())
-                                    .isEqualTo(device.getDeviceOperationalStatus().toString());
+                            assertThat(deviceConfig).hasToString(device.getDeviceOperationalStatus().toString());
 
                             assertThat(deviceConfig.getDeviceConfig().toString()).isNotNull();
 
diff --git a/src/automation/src/test/java/eu/teraflow/automation/ContextSubscriberTest.java b/src/automation/src/test/java/eu/teraflow/automation/ContextSubscriberTest.java
new file mode 100644
index 000000000..6039de58e
--- /dev/null
+++ b/src/automation/src/test/java/eu/teraflow/automation/ContextSubscriberTest.java
@@ -0,0 +1,199 @@
+package eu.teraflow.automation;
+
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import automation.Automation;
+import context.ContextOuterClass;
+import eu.teraflow.automation.context.ContextGateway;
+import eu.teraflow.automation.context.model.Event;
+import eu.teraflow.automation.context.model.EventTypeEnum;
+import eu.teraflow.automation.device.model.DeviceEvent;
+import io.quarkus.runtime.StartupEvent;
+import io.quarkus.test.junit.QuarkusTest;
+import io.quarkus.test.junit.mockito.InjectMock;
+import io.smallrye.mutiny.Multi;
+import java.util.UUID;
+import javax.inject.Inject;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mockito;
+
+@QuarkusTest
+class ContextSubscriberTest {
+
+    private static final String UUID_FOR_DEVICE_ROLE_ID =
+            UUID.fromString("0f14d0ab-9608-7862-a9e4-5ed26688389b").toString();
+    private static final String UUID_FOR_DEVICE_ID =
+            UUID.fromString("9f14d0ab-9608-7862-a9e4-5ed26688389c").toString();
+
+    @Inject ContextSubscriber contextSubscriber;
+
+    @InjectMock ContextGateway contextGateway;
+
+    @InjectMock AutomationService automationService;
+
+    @InjectMock AutomationConfiguration automationConfiguration;
+
+    @Test
+    void shouldCallAddDeviceUponCreateEvent() {
+        final var uuidForDeviceRoleId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ROLE_ID).build();
+
+        final var uuidForDeviceId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ID).build();
+
+        final var outDeviceId =
+                ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(uuidForDeviceId).build();
+
+        final var outDeviceRoleId =
+                Automation.DeviceRoleId.newBuilder()
+                        .setDevRoleId(uuidForDeviceRoleId)
+                        .setDevId(outDeviceId)
+                        .build();
+
+        String deviceId = outDeviceRoleId.getDevId().toString();
+
+        Event event = new Event(3.4, EventTypeEnum.CREATE);
+        DeviceEvent deviceEvent = new DeviceEvent(deviceId, event);
+        final var deviceEventsMulti = Multi.createFrom().item(deviceEvent);
+
+        Mockito.when(contextGateway.getDeviceEvents()).thenReturn(deviceEventsMulti);
+
+        contextSubscriber.listenForDeviceEvents();
+
+        verify(automationService, times(1)).addDevice(deviceId);
+    }
+
+    @Test
+    void shouldNotCallAddDeviceUponUpdateEvent() {
+        final var uuidForDeviceRoleId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ROLE_ID).build();
+
+        final var uuidForDeviceId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ID).build();
+
+        final var outDeviceId =
+                ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(uuidForDeviceId).build();
+
+        final var outDeviceRoleId =
+                Automation.DeviceRoleId.newBuilder()
+                        .setDevRoleId(uuidForDeviceRoleId)
+                        .setDevId(outDeviceId)
+                        .build();
+
+        String deviceId = outDeviceRoleId.getDevId().toString();
+
+        Event event = new Event(3.4, EventTypeEnum.UPDATE);
+        DeviceEvent deviceEvent = new DeviceEvent(deviceId, event);
+        final var deviceEventsMulti = Multi.createFrom().item(deviceEvent);
+
+        Mockito.when(contextGateway.getDeviceEvents()).thenReturn(deviceEventsMulti);
+
+        contextSubscriber.listenForDeviceEvents();
+
+        verify(automationService, times(0)).addDevice(deviceId);
+    }
+
+    @Test
+    void shouldNotCallAddDeviceUponRemoveEvent() {
+        final var uuidForDeviceRoleId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ROLE_ID).build();
+
+        final var uuidForDeviceId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ID).build();
+
+        final var outDeviceId =
+                ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(uuidForDeviceId).build();
+
+        final var outDeviceRoleId =
+                Automation.DeviceRoleId.newBuilder()
+                        .setDevRoleId(uuidForDeviceRoleId)
+                        .setDevId(outDeviceId)
+                        .build();
+
+        String deviceId = outDeviceRoleId.getDevId().toString();
+
+        Event event = new Event(3.4, EventTypeEnum.REMOVE);
+        DeviceEvent deviceEvent = new DeviceEvent(deviceId, event);
+        final var deviceEventsMulti = Multi.createFrom().item(deviceEvent);
+
+        Mockito.when(contextGateway.getDeviceEvents()).thenReturn(deviceEventsMulti);
+
+        contextSubscriber.listenForDeviceEvents();
+
+        verify(automationService, times(0)).addDevice(deviceId);
+    }
+
+    @Test
+    void shouldNotCallAddDeviceUponNullEvent() {
+        final var uuidForDeviceRoleId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ROLE_ID).build();
+
+        final var uuidForDeviceId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ID).build();
+
+        final var outDeviceId =
+                ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(uuidForDeviceId).build();
+
+        final var outDeviceRoleId =
+                Automation.DeviceRoleId.newBuilder()
+                        .setDevRoleId(uuidForDeviceRoleId)
+                        .setDevId(outDeviceId)
+                        .build();
+
+        String deviceId = outDeviceRoleId.getDevId().toString();
+
+        DeviceEvent deviceEvent = new DeviceEvent(deviceId, null);
+        final var deviceEventsMulti = Multi.createFrom().item(deviceEvent);
+
+        Mockito.when(contextGateway.getDeviceEvents()).thenReturn(deviceEventsMulti);
+
+        contextSubscriber.listenForDeviceEvents();
+
+        verify(automationService, times(0)).addDevice(deviceId);
+    }
+
+    @Test
+    void shouldCallListenForDeviceEventsUponStart() {
+        final var uuidForDeviceRoleId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ROLE_ID).build();
+
+        final var uuidForDeviceId =
+                ContextOuterClass.Uuid.newBuilder().setUuid(UUID_FOR_DEVICE_ID).build();
+
+        final var outDeviceId =
+                ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(uuidForDeviceId).build();
+
+        final var outDeviceRoleId =
+                Automation.DeviceRoleId.newBuilder()
+                        .setDevRoleId(uuidForDeviceRoleId)
+                        .setDevId(outDeviceId)
+                        .build();
+
+        String deviceId = outDeviceRoleId.getDevId().toString();
+
+        Event event = new Event(3.4, EventTypeEnum.CREATE);
+        DeviceEvent deviceEvent = new DeviceEvent(deviceId, event);
+        final var deviceEventsMulti = Multi.createFrom().item(deviceEvent);
+
+        Mockito.when(contextGateway.getDeviceEvents()).thenReturn(deviceEventsMulti);
+        Mockito.when(automationConfiguration.shouldSubscribeToContextComponent()).thenReturn(true);
+
+        StartupEvent y = new StartupEvent();
+        contextSubscriber.onStart(y);
+
+        verify(contextGateway, times(1)).getDeviceEvents();
+        verify(automationService, times(1)).addDevice(deviceId);
+    }
+
+    @Test
+    void shouldNotCallListenForDeviceEventsUponStart() {
+        final var automationConfiguration = Mockito.mock(AutomationConfiguration.class);
+        Mockito.when(automationConfiguration.shouldSubscribeToContextComponent()).thenReturn(false);
+
+        StartupEvent y = new StartupEvent();
+        contextSubscriber.onStart(y);
+
+        verify(contextGateway, times(0)).getDeviceEvents();
+    }
+}
diff --git a/src/automation/src/test/java/eu/teraflow/automation/MockAutomationConfiguration.java b/src/automation/src/test/java/eu/teraflow/automation/MockAutomationConfiguration.java
new file mode 100644
index 000000000..24c0433e0
--- /dev/null
+++ b/src/automation/src/test/java/eu/teraflow/automation/MockAutomationConfiguration.java
@@ -0,0 +1,18 @@
+package eu.teraflow.automation;
+
+import io.smallrye.config.SmallRyeConfig;
+import javax.enterprise.context.ApplicationScoped;
+import javax.inject.Inject;
+import javax.ws.rs.Produces;
+import org.eclipse.microprofile.config.Config;
+
+public class MockAutomationConfiguration {
+    @Inject Config config;
+
+    @Produces
+    @ApplicationScoped
+    @io.quarkus.test.Mock
+    AutomationConfiguration automationConfiguration() {
+        return config.unwrap(SmallRyeConfig.class).getConfigMapping(AutomationConfiguration.class);
+    }
+}
-- 
GitLab


From 19900089e72773ecdf68e413e418524fb4e1ea93 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Wed, 15 Jun 2022 12:24:44 +0300
Subject: [PATCH 47/60] feat(policy): add monitoring.proto file

---
 src/policy/src/main/proto/monitoring.proto    |    1 +
 .../grpc/monitoring/Monitoring.java           | 5629 +++++++++++++++++
 .../grpc/monitoring/MonitoringService.java    |   26 +
 .../monitoring/MonitoringServiceBean.java     |   68 +
 .../monitoring/MonitoringServiceClient.java   |   49 +
 .../monitoring/MonitoringServiceGrpc.java     |  638 ++
 .../MutinyMonitoringServiceGrpc.java          |  240 +
 7 files changed, 6651 insertions(+)
 create mode 120000 src/policy/src/main/proto/monitoring.proto
 create mode 100644 src/policy/target/generated-sources/grpc/monitoring/Monitoring.java
 create mode 100644 src/policy/target/generated-sources/grpc/monitoring/MonitoringService.java
 create mode 100644 src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java
 create mode 100644 src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java
 create mode 100644 src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java
 create mode 100644 src/policy/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java

diff --git a/src/policy/src/main/proto/monitoring.proto b/src/policy/src/main/proto/monitoring.proto
new file mode 120000
index 000000000..aceaa7328
--- /dev/null
+++ b/src/policy/src/main/proto/monitoring.proto
@@ -0,0 +1 @@
+../../../../../proto/monitoring.proto
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/monitoring/Monitoring.java b/src/policy/target/generated-sources/grpc/monitoring/Monitoring.java
new file mode 100644
index 000000000..1ef1f0c02
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/monitoring/Monitoring.java
@@ -0,0 +1,5629 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: monitoring.proto
+
+package monitoring;
+
+public final class Monitoring {
+  private Monitoring() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  public interface KpiDescriptorOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiDescriptor)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>string kpi_description = 1;</code>
+     * @return The kpiDescription.
+     */
+    java.lang.String getKpiDescription();
+    /**
+     * <code>string kpi_description = 1;</code>
+     * @return The bytes for kpiDescription.
+     */
+    com.google.protobuf.ByteString
+        getKpiDescriptionBytes();
+
+    /**
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * @return The enum numeric value on the wire for kpiSampleType.
+     */
+    int getKpiSampleTypeValue();
+    /**
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * @return The kpiSampleType.
+     */
+    kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType();
+
+    /**
+     * <code>.context.DeviceId device_id = 3;</code>
+     * @return Whether the deviceId field is set.
+     */
+    boolean hasDeviceId();
+    /**
+     * <code>.context.DeviceId device_id = 3;</code>
+     * @return The deviceId.
+     */
+    context.ContextOuterClass.DeviceId getDeviceId();
+    /**
+     * <code>.context.DeviceId device_id = 3;</code>
+     */
+    context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder();
+
+    /**
+     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * @return Whether the endpointId field is set.
+     */
+    boolean hasEndpointId();
+    /**
+     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * @return The endpointId.
+     */
+    context.ContextOuterClass.EndPointId getEndpointId();
+    /**
+     * <code>.context.EndPointId endpoint_id = 4;</code>
+     */
+    context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder();
+
+    /**
+     * <pre>
+     *  context.SliceId    slice_id    = 6;
+     * </pre>
+     *
+     * <code>.context.ServiceId service_id = 5;</code>
+     * @return Whether the serviceId field is set.
+     */
+    boolean hasServiceId();
+    /**
+     * <pre>
+     *  context.SliceId    slice_id    = 6;
+     * </pre>
+     *
+     * <code>.context.ServiceId service_id = 5;</code>
+     * @return The serviceId.
+     */
+    context.ContextOuterClass.ServiceId getServiceId();
+    /**
+     * <pre>
+     *  context.SliceId    slice_id    = 6;
+     * </pre>
+     *
+     * <code>.context.ServiceId service_id = 5;</code>
+     */
+    context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
+  }
+  /**
+   * Protobuf type {@code monitoring.KpiDescriptor}
+   */
+  public static final class KpiDescriptor extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:monitoring.KpiDescriptor)
+      KpiDescriptorOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use KpiDescriptor.newBuilder() to construct.
+    private KpiDescriptor(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private KpiDescriptor() {
+      kpiDescription_ = "";
+      kpiSampleType_ = 0;
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new KpiDescriptor();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private KpiDescriptor(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              kpiDescription_ = s;
+              break;
+            }
+            case 16: {
+              int rawValue = input.readEnum();
+
+              kpiSampleType_ = rawValue;
+              break;
+            }
+            case 26: {
+              context.ContextOuterClass.DeviceId.Builder subBuilder = null;
+              if (deviceId_ != null) {
+                subBuilder = deviceId_.toBuilder();
+              }
+              deviceId_ = input.readMessage(context.ContextOuterClass.DeviceId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(deviceId_);
+                deviceId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 34: {
+              context.ContextOuterClass.EndPointId.Builder subBuilder = null;
+              if (endpointId_ != null) {
+                subBuilder = endpointId_.toBuilder();
+              }
+              endpointId_ = input.readMessage(context.ContextOuterClass.EndPointId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(endpointId_);
+                endpointId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 42: {
+              context.ContextOuterClass.ServiceId.Builder subBuilder = null;
+              if (serviceId_ != null) {
+                subBuilder = serviceId_.toBuilder();
+              }
+              serviceId_ = input.readMessage(context.ContextOuterClass.ServiceId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(serviceId_);
+                serviceId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptor_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiDescriptor_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              monitoring.Monitoring.KpiDescriptor.class, monitoring.Monitoring.KpiDescriptor.Builder.class);
+    }
+
+    public static final int KPI_DESCRIPTION_FIELD_NUMBER = 1;
+    private volatile java.lang.Object kpiDescription_;
+    /**
+     * <code>string kpi_description = 1;</code>
+     * @return The kpiDescription.
+     */
+    @java.lang.Override
+    public java.lang.String getKpiDescription() {
+      java.lang.Object ref = kpiDescription_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        kpiDescription_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>string kpi_description = 1;</code>
+     * @return The bytes for kpiDescription.
+     */
+    @java.lang.Override
+    public com.google.protobuf.ByteString
+        getKpiDescriptionBytes() {
+      java.lang.Object ref = kpiDescription_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        kpiDescription_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int KPI_SAMPLE_TYPE_FIELD_NUMBER = 2;
+    private int kpiSampleType_;
+    /**
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * @return The enum numeric value on the wire for kpiSampleType.
+     */
+    @java.lang.Override public int getKpiSampleTypeValue() {
+      return kpiSampleType_;
+    }
+    /**
+     * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+     * @return The kpiSampleType.
+     */
+    @java.lang.Override public kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType() {
+      @SuppressWarnings("deprecation")
+      kpi_sample_types.KpiSampleTypes.KpiSampleType result = kpi_sample_types.KpiSampleTypes.KpiSampleType.valueOf(kpiSampleType_);
+      return result == null ? kpi_sample_types.KpiSampleTypes.KpiSampleType.UNRECOGNIZED : result;
+    }
+
+    public static final int DEVICE_ID_FIELD_NUMBER = 3;
+    private context.ContextOuterClass.DeviceId deviceId_;
+    /**
+     * <code>.context.DeviceId device_id = 3;</code>
+     * @return Whether the deviceId field is set.
+     */
+    @java.lang.Override
+    public boolean hasDeviceId() {
+      return deviceId_ != null;
+    }
+    /**
+     * <code>.context.DeviceId device_id = 3;</code>
+     * @return The deviceId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceId getDeviceId() {
+      return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
+    }
+    /**
+     * <code>.context.DeviceId device_id = 3;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
+      return getDeviceId();
+    }
+
+    public static final int ENDPOINT_ID_FIELD_NUMBER = 4;
+    private context.ContextOuterClass.EndPointId endpointId_;
+    /**
+     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * @return Whether the endpointId field is set.
+     */
+    @java.lang.Override
+    public boolean hasEndpointId() {
+      return endpointId_ != null;
+    }
+    /**
+     * <code>.context.EndPointId endpoint_id = 4;</code>
+     * @return The endpointId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.EndPointId getEndpointId() {
+      return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
+    }
+    /**
+     * <code>.context.EndPointId endpoint_id = 4;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
+      return getEndpointId();
+    }
+
+    public static final int SERVICE_ID_FIELD_NUMBER = 5;
+    private context.ContextOuterClass.ServiceId serviceId_;
+    /**
+     * <pre>
+     *  context.SliceId    slice_id    = 6;
+     * </pre>
+     *
+     * <code>.context.ServiceId service_id = 5;</code>
+     * @return Whether the serviceId field is set.
+     */
+    @java.lang.Override
+    public boolean hasServiceId() {
+      return serviceId_ != null;
+    }
+    /**
+     * <pre>
+     *  context.SliceId    slice_id    = 6;
+     * </pre>
+     *
+     * <code>.context.ServiceId service_id = 5;</code>
+     * @return The serviceId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ServiceId getServiceId() {
+      return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+    }
+    /**
+     * <pre>
+     *  context.SliceId    slice_id    = 6;
+     * </pre>
+     *
+     * <code>.context.ServiceId service_id = 5;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
+      return getServiceId();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (!getKpiDescriptionBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, kpiDescription_);
+      }
+      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
+        output.writeEnum(2, kpiSampleType_);
+      }
+      if (deviceId_ != null) {
+        output.writeMessage(3, getDeviceId());
+      }
+      if (endpointId_ != null) {
+        output.writeMessage(4, getEndpointId());
+      }
+      if (serviceId_ != null) {
+        output.writeMessage(5, getServiceId());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (!getKpiDescriptionBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, kpiDescription_);
+      }
+      if (kpiSampleType_ != kpi_sample_types.KpiSampleTypes.KpiSampleType.KPISAMPLETYPE_UNKNOWN.getNumber()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(2, kpiSampleType_);
+      }
+      if (deviceId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, getDeviceId());
+      }
+      if (endpointId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, getEndpointId());
+      }
+      if (serviceId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, getServiceId());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof monitoring.Monitoring.KpiDescriptor)) {
+        return super.equals(obj);
+      }
+      monitoring.Monitoring.KpiDescriptor other = (monitoring.Monitoring.KpiDescriptor) obj;
+
+      if (!getKpiDescription()
+          .equals(other.getKpiDescription())) return false;
+      if (kpiSampleType_ != other.kpiSampleType_) return false;
+      if (hasDeviceId() != other.hasDeviceId()) return false;
+      if (hasDeviceId()) {
+        if (!getDeviceId()
+            .equals(other.getDeviceId())) return false;
+      }
+      if (hasEndpointId() != other.hasEndpointId()) return false;
+      if (hasEndpointId()) {
+        if (!getEndpointId()
+            .equals(other.getEndpointId())) return false;
+      }
+      if (hasServiceId() != other.hasServiceId()) return false;
+      if (hasServiceId()) {
+        if (!getServiceId()
+            .equals(other.getServiceId())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + KPI_DESCRIPTION_FIELD_NUMBER;
+      hash = (53 * hash) + getKpiDescription().hashCode();
+      hash = (37 * hash) + KPI_SAMPLE_TYPE_FIELD_NUMBER;
+      hash = (53 * hash) + kpiSampleType_;
+      if (hasDeviceId()) {
+        hash = (37 * hash) + DEVICE_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getDeviceId().hashCode();
+      }
+      if (hasEndpointId()) {
+        hash = (37 * hash) + ENDPOINT_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getEndpointId().hashCode();
+      }
+      if (hasServiceId()) {
+        hash = (37 * hash) + SERVICE_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getServiceId().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiDescriptor parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(monitoring.Monitoring.KpiDescriptor prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code monitoring.KpiDescriptor}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiDescriptor)
+        monitoring.Monitoring.KpiDescriptorOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptor_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptor_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.KpiDescriptor.class, monitoring.Monitoring.KpiDescriptor.Builder.class);
+      }
+
+      // Construct using monitoring.Monitoring.KpiDescriptor.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        kpiDescription_ = "";
+
+        kpiSampleType_ = 0;
+
+        if (deviceIdBuilder_ == null) {
+          deviceId_ = null;
+        } else {
+          deviceId_ = null;
+          deviceIdBuilder_ = null;
+        }
+        if (endpointIdBuilder_ == null) {
+          endpointId_ = null;
+        } else {
+          endpointId_ = null;
+          endpointIdBuilder_ = null;
+        }
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = null;
+        } else {
+          serviceId_ = null;
+          serviceIdBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiDescriptor_descriptor;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiDescriptor getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiDescriptor.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiDescriptor build() {
+        monitoring.Monitoring.KpiDescriptor result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiDescriptor buildPartial() {
+        monitoring.Monitoring.KpiDescriptor result = new monitoring.Monitoring.KpiDescriptor(this);
+        result.kpiDescription_ = kpiDescription_;
+        result.kpiSampleType_ = kpiSampleType_;
+        if (deviceIdBuilder_ == null) {
+          result.deviceId_ = deviceId_;
+        } else {
+          result.deviceId_ = deviceIdBuilder_.build();
+        }
+        if (endpointIdBuilder_ == null) {
+          result.endpointId_ = endpointId_;
+        } else {
+          result.endpointId_ = endpointIdBuilder_.build();
+        }
+        if (serviceIdBuilder_ == null) {
+          result.serviceId_ = serviceId_;
+        } else {
+          result.serviceId_ = serviceIdBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.KpiDescriptor) {
+          return mergeFrom((monitoring.Monitoring.KpiDescriptor)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(monitoring.Monitoring.KpiDescriptor other) {
+        if (other == monitoring.Monitoring.KpiDescriptor.getDefaultInstance()) return this;
+        if (!other.getKpiDescription().isEmpty()) {
+          kpiDescription_ = other.kpiDescription_;
+          onChanged();
+        }
+        if (other.kpiSampleType_ != 0) {
+          setKpiSampleTypeValue(other.getKpiSampleTypeValue());
+        }
+        if (other.hasDeviceId()) {
+          mergeDeviceId(other.getDeviceId());
+        }
+        if (other.hasEndpointId()) {
+          mergeEndpointId(other.getEndpointId());
+        }
+        if (other.hasServiceId()) {
+          mergeServiceId(other.getServiceId());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.KpiDescriptor parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.KpiDescriptor) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private java.lang.Object kpiDescription_ = "";
+      /**
+       * <code>string kpi_description = 1;</code>
+       * @return The kpiDescription.
+       */
+      public java.lang.String getKpiDescription() {
+        java.lang.Object ref = kpiDescription_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          kpiDescription_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>string kpi_description = 1;</code>
+       * @return The bytes for kpiDescription.
+       */
+      public com.google.protobuf.ByteString
+          getKpiDescriptionBytes() {
+        java.lang.Object ref = kpiDescription_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          kpiDescription_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string kpi_description = 1;</code>
+       * @param value The kpiDescription to set.
+       * @return This builder for chaining.
+       */
+      public Builder setKpiDescription(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        kpiDescription_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string kpi_description = 1;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearKpiDescription() {
+        
+        kpiDescription_ = getDefaultInstance().getKpiDescription();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string kpi_description = 1;</code>
+       * @param value The bytes for kpiDescription to set.
+       * @return This builder for chaining.
+       */
+      public Builder setKpiDescriptionBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        kpiDescription_ = value;
+        onChanged();
+        return this;
+      }
+
+      private int kpiSampleType_ = 0;
+      /**
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+       * @return The enum numeric value on the wire for kpiSampleType.
+       */
+      @java.lang.Override public int getKpiSampleTypeValue() {
+        return kpiSampleType_;
+      }
+      /**
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+       * @param value The enum numeric value on the wire for kpiSampleType to set.
+       * @return This builder for chaining.
+       */
+      public Builder setKpiSampleTypeValue(int value) {
+        
+        kpiSampleType_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+       * @return The kpiSampleType.
+       */
+      @java.lang.Override
+      public kpi_sample_types.KpiSampleTypes.KpiSampleType getKpiSampleType() {
+        @SuppressWarnings("deprecation")
+        kpi_sample_types.KpiSampleTypes.KpiSampleType result = kpi_sample_types.KpiSampleTypes.KpiSampleType.valueOf(kpiSampleType_);
+        return result == null ? kpi_sample_types.KpiSampleTypes.KpiSampleType.UNRECOGNIZED : result;
+      }
+      /**
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+       * @param value The kpiSampleType to set.
+       * @return This builder for chaining.
+       */
+      public Builder setKpiSampleType(kpi_sample_types.KpiSampleTypes.KpiSampleType value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        
+        kpiSampleType_ = value.getNumber();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.kpi_sample_types.KpiSampleType kpi_sample_type = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearKpiSampleType() {
+        
+        kpiSampleType_ = 0;
+        onChanged();
+        return this;
+      }
+
+      private context.ContextOuterClass.DeviceId deviceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder> deviceIdBuilder_;
+      /**
+       * <code>.context.DeviceId device_id = 3;</code>
+       * @return Whether the deviceId field is set.
+       */
+      public boolean hasDeviceId() {
+        return deviceIdBuilder_ != null || deviceId_ != null;
+      }
+      /**
+       * <code>.context.DeviceId device_id = 3;</code>
+       * @return The deviceId.
+       */
+      public context.ContextOuterClass.DeviceId getDeviceId() {
+        if (deviceIdBuilder_ == null) {
+          return deviceId_ == null ? context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
+        } else {
+          return deviceIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.DeviceId device_id = 3;</code>
+       */
+      public Builder setDeviceId(context.ContextOuterClass.DeviceId value) {
+        if (deviceIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          deviceId_ = value;
+          onChanged();
+        } else {
+          deviceIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceId device_id = 3;</code>
+       */
+      public Builder setDeviceId(
+          context.ContextOuterClass.DeviceId.Builder builderForValue) {
+        if (deviceIdBuilder_ == null) {
+          deviceId_ = builderForValue.build();
+          onChanged();
+        } else {
+          deviceIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceId device_id = 3;</code>
+       */
+      public Builder mergeDeviceId(context.ContextOuterClass.DeviceId value) {
+        if (deviceIdBuilder_ == null) {
+          if (deviceId_ != null) {
+            deviceId_ =
+              context.ContextOuterClass.DeviceId.newBuilder(deviceId_).mergeFrom(value).buildPartial();
+          } else {
+            deviceId_ = value;
+          }
+          onChanged();
+        } else {
+          deviceIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceId device_id = 3;</code>
+       */
+      public Builder clearDeviceId() {
+        if (deviceIdBuilder_ == null) {
+          deviceId_ = null;
+          onChanged();
+        } else {
+          deviceId_ = null;
+          deviceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.DeviceId device_id = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceId.Builder getDeviceIdBuilder() {
+        
+        onChanged();
+        return getDeviceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.DeviceId device_id = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceIdOrBuilder getDeviceIdOrBuilder() {
+        if (deviceIdBuilder_ != null) {
+          return deviceIdBuilder_.getMessageOrBuilder();
+        } else {
+          return deviceId_ == null ?
+              context.ContextOuterClass.DeviceId.getDefaultInstance() : deviceId_;
+        }
+      }
+      /**
+       * <code>.context.DeviceId device_id = 3;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder> 
+          getDeviceIdFieldBuilder() {
+        if (deviceIdBuilder_ == null) {
+          deviceIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder>(
+                  getDeviceId(),
+                  getParentForChildren(),
+                  isClean());
+          deviceId_ = null;
+        }
+        return deviceIdBuilder_;
+      }
+
+      private context.ContextOuterClass.EndPointId endpointId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder> endpointIdBuilder_;
+      /**
+       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * @return Whether the endpointId field is set.
+       */
+      public boolean hasEndpointId() {
+        return endpointIdBuilder_ != null || endpointId_ != null;
+      }
+      /**
+       * <code>.context.EndPointId endpoint_id = 4;</code>
+       * @return The endpointId.
+       */
+      public context.ContextOuterClass.EndPointId getEndpointId() {
+        if (endpointIdBuilder_ == null) {
+          return endpointId_ == null ? context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
+        } else {
+          return endpointIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.EndPointId endpoint_id = 4;</code>
+       */
+      public Builder setEndpointId(context.ContextOuterClass.EndPointId value) {
+        if (endpointIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          endpointId_ = value;
+          onChanged();
+        } else {
+          endpointIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.EndPointId endpoint_id = 4;</code>
+       */
+      public Builder setEndpointId(
+          context.ContextOuterClass.EndPointId.Builder builderForValue) {
+        if (endpointIdBuilder_ == null) {
+          endpointId_ = builderForValue.build();
+          onChanged();
+        } else {
+          endpointIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.EndPointId endpoint_id = 4;</code>
+       */
+      public Builder mergeEndpointId(context.ContextOuterClass.EndPointId value) {
+        if (endpointIdBuilder_ == null) {
+          if (endpointId_ != null) {
+            endpointId_ =
+              context.ContextOuterClass.EndPointId.newBuilder(endpointId_).mergeFrom(value).buildPartial();
+          } else {
+            endpointId_ = value;
+          }
+          onChanged();
+        } else {
+          endpointIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.EndPointId endpoint_id = 4;</code>
+       */
+      public Builder clearEndpointId() {
+        if (endpointIdBuilder_ == null) {
+          endpointId_ = null;
+          onChanged();
+        } else {
+          endpointId_ = null;
+          endpointIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.EndPointId endpoint_id = 4;</code>
+       */
+      public context.ContextOuterClass.EndPointId.Builder getEndpointIdBuilder() {
+        
+        onChanged();
+        return getEndpointIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.EndPointId endpoint_id = 4;</code>
+       */
+      public context.ContextOuterClass.EndPointIdOrBuilder getEndpointIdOrBuilder() {
+        if (endpointIdBuilder_ != null) {
+          return endpointIdBuilder_.getMessageOrBuilder();
+        } else {
+          return endpointId_ == null ?
+              context.ContextOuterClass.EndPointId.getDefaultInstance() : endpointId_;
+        }
+      }
+      /**
+       * <code>.context.EndPointId endpoint_id = 4;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder> 
+          getEndpointIdFieldBuilder() {
+        if (endpointIdBuilder_ == null) {
+          endpointIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.EndPointId, context.ContextOuterClass.EndPointId.Builder, context.ContextOuterClass.EndPointIdOrBuilder>(
+                  getEndpointId(),
+                  getParentForChildren(),
+                  isClean());
+          endpointId_ = null;
+        }
+        return endpointIdBuilder_;
+      }
+
+      private context.ContextOuterClass.ServiceId serviceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> serviceIdBuilder_;
+      /**
+       * <pre>
+       *  context.SliceId    slice_id    = 6;
+       * </pre>
+       *
+       * <code>.context.ServiceId service_id = 5;</code>
+       * @return Whether the serviceId field is set.
+       */
+      public boolean hasServiceId() {
+        return serviceIdBuilder_ != null || serviceId_ != null;
+      }
+      /**
+       * <pre>
+       *  context.SliceId    slice_id    = 6;
+       * </pre>
+       *
+       * <code>.context.ServiceId service_id = 5;</code>
+       * @return The serviceId.
+       */
+      public context.ContextOuterClass.ServiceId getServiceId() {
+        if (serviceIdBuilder_ == null) {
+          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+        } else {
+          return serviceIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <pre>
+       *  context.SliceId    slice_id    = 6;
+       * </pre>
+       *
+       * <code>.context.ServiceId service_id = 5;</code>
+       */
+      public Builder setServiceId(context.ContextOuterClass.ServiceId value) {
+        if (serviceIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          serviceId_ = value;
+          onChanged();
+        } else {
+          serviceIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       *  context.SliceId    slice_id    = 6;
+       * </pre>
+       *
+       * <code>.context.ServiceId service_id = 5;</code>
+       */
+      public Builder setServiceId(
+          context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = builderForValue.build();
+          onChanged();
+        } else {
+          serviceIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       *  context.SliceId    slice_id    = 6;
+       * </pre>
+       *
+       * <code>.context.ServiceId service_id = 5;</code>
+       */
+      public Builder mergeServiceId(context.ContextOuterClass.ServiceId value) {
+        if (serviceIdBuilder_ == null) {
+          if (serviceId_ != null) {
+            serviceId_ =
+              context.ContextOuterClass.ServiceId.newBuilder(serviceId_).mergeFrom(value).buildPartial();
+          } else {
+            serviceId_ = value;
+          }
+          onChanged();
+        } else {
+          serviceIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       *  context.SliceId    slice_id    = 6;
+       * </pre>
+       *
+       * <code>.context.ServiceId service_id = 5;</code>
+       */
+      public Builder clearServiceId() {
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = null;
+          onChanged();
+        } else {
+          serviceId_ = null;
+          serviceIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       *  context.SliceId    slice_id    = 6;
+       * </pre>
+       *
+       * <code>.context.ServiceId service_id = 5;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
+        
+        onChanged();
+        return getServiceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       *  context.SliceId    slice_id    = 6;
+       * </pre>
+       *
+       * <code>.context.ServiceId service_id = 5;</code>
+       */
+      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
+        if (serviceIdBuilder_ != null) {
+          return serviceIdBuilder_.getMessageOrBuilder();
+        } else {
+          return serviceId_ == null ?
+              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+        }
+      }
+      /**
+       * <pre>
+       *  context.SliceId    slice_id    = 6;
+       * </pre>
+       *
+       * <code>.context.ServiceId service_id = 5;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> 
+          getServiceIdFieldBuilder() {
+        if (serviceIdBuilder_ == null) {
+          serviceIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder>(
+                  getServiceId(),
+                  getParentForChildren(),
+                  isClean());
+          serviceId_ = null;
+        }
+        return serviceIdBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiDescriptor)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.KpiDescriptor)
+    private static final monitoring.Monitoring.KpiDescriptor DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiDescriptor();
+    }
+
+    public static monitoring.Monitoring.KpiDescriptor getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<KpiDescriptor>
+        PARSER = new com.google.protobuf.AbstractParser<KpiDescriptor>() {
+      @java.lang.Override
+      public KpiDescriptor parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new KpiDescriptor(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<KpiDescriptor> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<KpiDescriptor> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.KpiDescriptor getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface MonitorKpiRequestOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.MonitorKpiRequest)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
+     */
+    boolean hasKpiId();
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return The kpiId.
+     */
+    monitoring.Monitoring.KpiId getKpiId();
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     */
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
+
+    /**
+     * <code>float sampling_duration_s = 2;</code>
+     * @return The samplingDurationS.
+     */
+    float getSamplingDurationS();
+
+    /**
+     * <code>float sampling_interval_s = 3;</code>
+     * @return The samplingIntervalS.
+     */
+    float getSamplingIntervalS();
+  }
+  /**
+   * Protobuf type {@code monitoring.MonitorKpiRequest}
+   */
+  public static final class MonitorKpiRequest extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:monitoring.MonitorKpiRequest)
+      MonitorKpiRequestOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use MonitorKpiRequest.newBuilder() to construct.
+    private MonitorKpiRequest(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private MonitorKpiRequest() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new MonitorKpiRequest();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private MonitorKpiRequest(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              monitoring.Monitoring.KpiId.Builder subBuilder = null;
+              if (kpiId_ != null) {
+                subBuilder = kpiId_.toBuilder();
+              }
+              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(kpiId_);
+                kpiId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 21: {
+
+              samplingDurationS_ = input.readFloat();
+              break;
+            }
+            case 29: {
+
+              samplingIntervalS_ = input.readFloat();
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              monitoring.Monitoring.MonitorKpiRequest.class, monitoring.Monitoring.MonitorKpiRequest.Builder.class);
+    }
+
+    public static final int KPI_ID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.KpiId kpiId_;
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
+     */
+    @java.lang.Override
+    public boolean hasKpiId() {
+      return kpiId_ != null;
+    }
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return The kpiId.
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiId getKpiId() {
+      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+    }
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+      return getKpiId();
+    }
+
+    public static final int SAMPLING_DURATION_S_FIELD_NUMBER = 2;
+    private float samplingDurationS_;
+    /**
+     * <code>float sampling_duration_s = 2;</code>
+     * @return The samplingDurationS.
+     */
+    @java.lang.Override
+    public float getSamplingDurationS() {
+      return samplingDurationS_;
+    }
+
+    public static final int SAMPLING_INTERVAL_S_FIELD_NUMBER = 3;
+    private float samplingIntervalS_;
+    /**
+     * <code>float sampling_interval_s = 3;</code>
+     * @return The samplingIntervalS.
+     */
+    @java.lang.Override
+    public float getSamplingIntervalS() {
+      return samplingIntervalS_;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (kpiId_ != null) {
+        output.writeMessage(1, getKpiId());
+      }
+      if (samplingDurationS_ != 0F) {
+        output.writeFloat(2, samplingDurationS_);
+      }
+      if (samplingIntervalS_ != 0F) {
+        output.writeFloat(3, samplingIntervalS_);
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getKpiId());
+      }
+      if (samplingDurationS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(2, samplingDurationS_);
+      }
+      if (samplingIntervalS_ != 0F) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(3, samplingIntervalS_);
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof monitoring.Monitoring.MonitorKpiRequest)) {
+        return super.equals(obj);
+      }
+      monitoring.Monitoring.MonitorKpiRequest other = (monitoring.Monitoring.MonitorKpiRequest) obj;
+
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
+      }
+      if (java.lang.Float.floatToIntBits(getSamplingDurationS())
+          != java.lang.Float.floatToIntBits(
+              other.getSamplingDurationS())) return false;
+      if (java.lang.Float.floatToIntBits(getSamplingIntervalS())
+          != java.lang.Float.floatToIntBits(
+              other.getSamplingIntervalS())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasKpiId()) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiId().hashCode();
+      }
+      hash = (37 * hash) + SAMPLING_DURATION_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSamplingDurationS());
+      hash = (37 * hash) + SAMPLING_INTERVAL_S_FIELD_NUMBER;
+      hash = (53 * hash) + java.lang.Float.floatToIntBits(
+          getSamplingIntervalS());
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.MonitorKpiRequest parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(monitoring.Monitoring.MonitorKpiRequest prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code monitoring.MonitorKpiRequest}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.MonitorKpiRequest)
+        monitoring.Monitoring.MonitorKpiRequestOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.MonitorKpiRequest.class, monitoring.Monitoring.MonitorKpiRequest.Builder.class);
+      }
+
+      // Construct using monitoring.Monitoring.MonitorKpiRequest.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+        samplingDurationS_ = 0F;
+
+        samplingIntervalS_ = 0F;
+
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_MonitorKpiRequest_descriptor;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.MonitorKpiRequest getDefaultInstanceForType() {
+        return monitoring.Monitoring.MonitorKpiRequest.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.MonitorKpiRequest build() {
+        monitoring.Monitoring.MonitorKpiRequest result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.MonitorKpiRequest buildPartial() {
+        monitoring.Monitoring.MonitorKpiRequest result = new monitoring.Monitoring.MonitorKpiRequest(this);
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
+        result.samplingDurationS_ = samplingDurationS_;
+        result.samplingIntervalS_ = samplingIntervalS_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.MonitorKpiRequest) {
+          return mergeFrom((monitoring.Monitoring.MonitorKpiRequest)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(monitoring.Monitoring.MonitorKpiRequest other) {
+        if (other == monitoring.Monitoring.MonitorKpiRequest.getDefaultInstance()) return this;
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
+        }
+        if (other.getSamplingDurationS() != 0F) {
+          setSamplingDurationS(other.getSamplingDurationS());
+        }
+        if (other.getSamplingIntervalS() != 0F) {
+          setSamplingIntervalS(other.getSamplingIntervalS());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.MonitorKpiRequest parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.MonitorKpiRequest) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private monitoring.Monitoring.KpiId kpiId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * @return Whether the kpiId field is set.
+       */
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * @return The kpiId.
+       */
+      public monitoring.Monitoring.KpiId getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+        } else {
+          return kpiIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          kpiId_ = value;
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder setKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder mergeKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (kpiId_ != null) {
+            kpiId_ =
+              monitoring.Monitoring.KpiId.newBuilder(kpiId_).mergeFrom(value).buildPartial();
+          } else {
+            kpiId_ = value;
+          }
+          onChanged();
+        } else {
+          kpiIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
+        
+        onChanged();
+        return getKpiIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
+        } else {
+          return kpiId_ == null ?
+              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+        }
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
+                  getKpiId(),
+                  getParentForChildren(),
+                  isClean());
+          kpiId_ = null;
+        }
+        return kpiIdBuilder_;
+      }
+
+      private float samplingDurationS_ ;
+      /**
+       * <code>float sampling_duration_s = 2;</code>
+       * @return The samplingDurationS.
+       */
+      @java.lang.Override
+      public float getSamplingDurationS() {
+        return samplingDurationS_;
+      }
+      /**
+       * <code>float sampling_duration_s = 2;</code>
+       * @param value The samplingDurationS to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSamplingDurationS(float value) {
+        
+        samplingDurationS_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float sampling_duration_s = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSamplingDurationS() {
+        
+        samplingDurationS_ = 0F;
+        onChanged();
+        return this;
+      }
+
+      private float samplingIntervalS_ ;
+      /**
+       * <code>float sampling_interval_s = 3;</code>
+       * @return The samplingIntervalS.
+       */
+      @java.lang.Override
+      public float getSamplingIntervalS() {
+        return samplingIntervalS_;
+      }
+      /**
+       * <code>float sampling_interval_s = 3;</code>
+       * @param value The samplingIntervalS to set.
+       * @return This builder for chaining.
+       */
+      public Builder setSamplingIntervalS(float value) {
+        
+        samplingIntervalS_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float sampling_interval_s = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearSamplingIntervalS() {
+        
+        samplingIntervalS_ = 0F;
+        onChanged();
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:monitoring.MonitorKpiRequest)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.MonitorKpiRequest)
+    private static final monitoring.Monitoring.MonitorKpiRequest DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.MonitorKpiRequest();
+    }
+
+    public static monitoring.Monitoring.MonitorKpiRequest getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<MonitorKpiRequest>
+        PARSER = new com.google.protobuf.AbstractParser<MonitorKpiRequest>() {
+      @java.lang.Override
+      public MonitorKpiRequest parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new MonitorKpiRequest(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<MonitorKpiRequest> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<MonitorKpiRequest> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.MonitorKpiRequest getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface KpiIdOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiId)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.context.Uuid kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
+     */
+    boolean hasKpiId();
+    /**
+     * <code>.context.Uuid kpi_id = 1;</code>
+     * @return The kpiId.
+     */
+    context.ContextOuterClass.Uuid getKpiId();
+    /**
+     * <code>.context.Uuid kpi_id = 1;</code>
+     */
+    context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder();
+  }
+  /**
+   * Protobuf type {@code monitoring.KpiId}
+   */
+  public static final class KpiId extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:monitoring.KpiId)
+      KpiIdOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use KpiId.newBuilder() to construct.
+    private KpiId(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private KpiId() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new KpiId();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private KpiId(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              context.ContextOuterClass.Uuid.Builder subBuilder = null;
+              if (kpiId_ != null) {
+                subBuilder = kpiId_.toBuilder();
+              }
+              kpiId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(kpiId_);
+                kpiId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiId_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiId_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              monitoring.Monitoring.KpiId.class, monitoring.Monitoring.KpiId.Builder.class);
+    }
+
+    public static final int KPI_ID_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Uuid kpiId_;
+    /**
+     * <code>.context.Uuid kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
+     */
+    @java.lang.Override
+    public boolean hasKpiId() {
+      return kpiId_ != null;
+    }
+    /**
+     * <code>.context.Uuid kpi_id = 1;</code>
+     * @return The kpiId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.Uuid getKpiId() {
+      return kpiId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+    }
+    /**
+     * <code>.context.Uuid kpi_id = 1;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder() {
+      return getKpiId();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (kpiId_ != null) {
+        output.writeMessage(1, getKpiId());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getKpiId());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof monitoring.Monitoring.KpiId)) {
+        return super.equals(obj);
+      }
+      monitoring.Monitoring.KpiId other = (monitoring.Monitoring.KpiId) obj;
+
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasKpiId()) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiId().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static monitoring.Monitoring.KpiId parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiId parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiId parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiId parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiId parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiId parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiId parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiId parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiId parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiId parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiId parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiId parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(monitoring.Monitoring.KpiId prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code monitoring.KpiId}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiId)
+        monitoring.Monitoring.KpiIdOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiId_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiId_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.KpiId.class, monitoring.Monitoring.KpiId.Builder.class);
+      }
+
+      // Construct using monitoring.Monitoring.KpiId.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiId_descriptor;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiId.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiId build() {
+        monitoring.Monitoring.KpiId result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiId buildPartial() {
+        monitoring.Monitoring.KpiId result = new monitoring.Monitoring.KpiId(this);
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.KpiId) {
+          return mergeFrom((monitoring.Monitoring.KpiId)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(monitoring.Monitoring.KpiId other) {
+        if (other == monitoring.Monitoring.KpiId.getDefaultInstance()) return this;
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.KpiId parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.KpiId) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private context.ContextOuterClass.Uuid kpiId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> kpiIdBuilder_;
+      /**
+       * <code>.context.Uuid kpi_id = 1;</code>
+       * @return Whether the kpiId field is set.
+       */
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
+      }
+      /**
+       * <code>.context.Uuid kpi_id = 1;</code>
+       * @return The kpiId.
+       */
+      public context.ContextOuterClass.Uuid getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+        } else {
+          return kpiIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.context.Uuid kpi_id = 1;</code>
+       */
+      public Builder setKpiId(context.ContextOuterClass.Uuid value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          kpiId_ = value;
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid kpi_id = 1;</code>
+       */
+      public Builder setKpiId(
+          context.ContextOuterClass.Uuid.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid kpi_id = 1;</code>
+       */
+      public Builder mergeKpiId(context.ContextOuterClass.Uuid value) {
+        if (kpiIdBuilder_ == null) {
+          if (kpiId_ != null) {
+            kpiId_ =
+              context.ContextOuterClass.Uuid.newBuilder(kpiId_).mergeFrom(value).buildPartial();
+          } else {
+            kpiId_ = value;
+          }
+          onChanged();
+        } else {
+          kpiIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid kpi_id = 1;</code>
+       */
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.context.Uuid kpi_id = 1;</code>
+       */
+      public context.ContextOuterClass.Uuid.Builder getKpiIdBuilder() {
+        
+        onChanged();
+        return getKpiIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.context.Uuid kpi_id = 1;</code>
+       */
+      public context.ContextOuterClass.UuidOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
+        } else {
+          return kpiId_ == null ?
+              context.ContextOuterClass.Uuid.getDefaultInstance() : kpiId_;
+        }
+      }
+      /**
+       * <code>.context.Uuid kpi_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
+                  getKpiId(),
+                  getParentForChildren(),
+                  isClean());
+          kpiId_ = null;
+        }
+        return kpiIdBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiId)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.KpiId)
+    private static final monitoring.Monitoring.KpiId DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiId();
+    }
+
+    public static monitoring.Monitoring.KpiId getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<KpiId>
+        PARSER = new com.google.protobuf.AbstractParser<KpiId>() {
+      @java.lang.Override
+      public KpiId parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new KpiId(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<KpiId> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<KpiId> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.KpiId getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface KpiOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.Kpi)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
+     */
+    boolean hasKpiId();
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return The kpiId.
+     */
+    monitoring.Monitoring.KpiId getKpiId();
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     */
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
+
+    /**
+     * <code>string timestamp = 2;</code>
+     * @return The timestamp.
+     */
+    java.lang.String getTimestamp();
+    /**
+     * <code>string timestamp = 2;</code>
+     * @return The bytes for timestamp.
+     */
+    com.google.protobuf.ByteString
+        getTimestampBytes();
+
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 4;</code>
+     * @return Whether the kpiValue field is set.
+     */
+    boolean hasKpiValue();
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 4;</code>
+     * @return The kpiValue.
+     */
+    monitoring.Monitoring.KpiValue getKpiValue();
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 4;</code>
+     */
+    monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder();
+  }
+  /**
+   * Protobuf type {@code monitoring.Kpi}
+   */
+  public static final class Kpi extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:monitoring.Kpi)
+      KpiOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use Kpi.newBuilder() to construct.
+    private Kpi(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private Kpi() {
+      timestamp_ = "";
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new Kpi();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private Kpi(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              monitoring.Monitoring.KpiId.Builder subBuilder = null;
+              if (kpiId_ != null) {
+                subBuilder = kpiId_.toBuilder();
+              }
+              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(kpiId_);
+                kpiId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              java.lang.String s = input.readStringRequireUtf8();
+
+              timestamp_ = s;
+              break;
+            }
+            case 34: {
+              monitoring.Monitoring.KpiValue.Builder subBuilder = null;
+              if (kpiValue_ != null) {
+                subBuilder = kpiValue_.toBuilder();
+              }
+              kpiValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(kpiValue_);
+                kpiValue_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
+    }
+
+    public static final int KPI_ID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.KpiId kpiId_;
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return Whether the kpiId field is set.
+     */
+    @java.lang.Override
+    public boolean hasKpiId() {
+      return kpiId_ != null;
+    }
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     * @return The kpiId.
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiId getKpiId() {
+      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+    }
+    /**
+     * <code>.monitoring.KpiId kpi_id = 1;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+      return getKpiId();
+    }
+
+    public static final int TIMESTAMP_FIELD_NUMBER = 2;
+    private volatile java.lang.Object timestamp_;
+    /**
+     * <code>string timestamp = 2;</code>
+     * @return The timestamp.
+     */
+    @java.lang.Override
+    public java.lang.String getTimestamp() {
+      java.lang.Object ref = timestamp_;
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        timestamp_ = s;
+        return s;
+      }
+    }
+    /**
+     * <code>string timestamp = 2;</code>
+     * @return The bytes for timestamp.
+     */
+    @java.lang.Override
+    public com.google.protobuf.ByteString
+        getTimestampBytes() {
+      java.lang.Object ref = timestamp_;
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        timestamp_ = b;
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int KPI_VALUE_FIELD_NUMBER = 4;
+    private monitoring.Monitoring.KpiValue kpiValue_;
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 4;</code>
+     * @return Whether the kpiValue field is set.
+     */
+    @java.lang.Override
+    public boolean hasKpiValue() {
+      return kpiValue_ != null;
+    }
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 4;</code>
+     * @return The kpiValue.
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValue getKpiValue() {
+      return kpiValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+    }
+    /**
+     * <code>.monitoring.KpiValue kpi_value = 4;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
+      return getKpiValue();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (kpiId_ != null) {
+        output.writeMessage(1, getKpiId());
+      }
+      if (!getTimestampBytes().isEmpty()) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, timestamp_);
+      }
+      if (kpiValue_ != null) {
+        output.writeMessage(4, getKpiValue());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getKpiId());
+      }
+      if (!getTimestampBytes().isEmpty()) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(2, timestamp_);
+      }
+      if (kpiValue_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, getKpiValue());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof monitoring.Monitoring.Kpi)) {
+        return super.equals(obj);
+      }
+      monitoring.Monitoring.Kpi other = (monitoring.Monitoring.Kpi) obj;
+
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
+      }
+      if (!getTimestamp()
+          .equals(other.getTimestamp())) return false;
+      if (hasKpiValue() != other.hasKpiValue()) return false;
+      if (hasKpiValue()) {
+        if (!getKpiValue()
+            .equals(other.getKpiValue())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasKpiId()) {
+        hash = (37 * hash) + KPI_ID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiId().hashCode();
+      }
+      hash = (37 * hash) + TIMESTAMP_FIELD_NUMBER;
+      hash = (53 * hash) + getTimestamp().hashCode();
+      if (hasKpiValue()) {
+        hash = (37 * hash) + KPI_VALUE_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiValue().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static monitoring.Monitoring.Kpi parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.Kpi parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.Kpi parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.Kpi parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.Kpi parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.Kpi parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.Kpi parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.Kpi parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.Kpi parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.Kpi parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.Kpi parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.Kpi parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(monitoring.Monitoring.Kpi prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code monitoring.Kpi}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.Kpi)
+        monitoring.Monitoring.KpiOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_Kpi_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.Kpi.class, monitoring.Monitoring.Kpi.Builder.class);
+      }
+
+      // Construct using monitoring.Monitoring.Kpi.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+        timestamp_ = "";
+
+        if (kpiValueBuilder_ == null) {
+          kpiValue_ = null;
+        } else {
+          kpiValue_ = null;
+          kpiValueBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_Kpi_descriptor;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
+        return monitoring.Monitoring.Kpi.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.Kpi build() {
+        monitoring.Monitoring.Kpi result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.Kpi buildPartial() {
+        monitoring.Monitoring.Kpi result = new monitoring.Monitoring.Kpi(this);
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
+        result.timestamp_ = timestamp_;
+        if (kpiValueBuilder_ == null) {
+          result.kpiValue_ = kpiValue_;
+        } else {
+          result.kpiValue_ = kpiValueBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.Kpi) {
+          return mergeFrom((monitoring.Monitoring.Kpi)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(monitoring.Monitoring.Kpi other) {
+        if (other == monitoring.Monitoring.Kpi.getDefaultInstance()) return this;
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
+        }
+        if (!other.getTimestamp().isEmpty()) {
+          timestamp_ = other.timestamp_;
+          onChanged();
+        }
+        if (other.hasKpiValue()) {
+          mergeKpiValue(other.getKpiValue());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.Kpi parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.Kpi) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private monitoring.Monitoring.KpiId kpiId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * @return Whether the kpiId field is set.
+       */
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       * @return The kpiId.
+       */
+      public monitoring.Monitoring.KpiId getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+        } else {
+          return kpiIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          kpiId_ = value;
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder setKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder mergeKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (kpiId_ != null) {
+            kpiId_ =
+              monitoring.Monitoring.KpiId.newBuilder(kpiId_).mergeFrom(value).buildPartial();
+          } else {
+            kpiId_ = value;
+          }
+          onChanged();
+        } else {
+          kpiIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
+        
+        onChanged();
+        return getKpiIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
+        } else {
+          return kpiId_ == null ?
+              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+        }
+      }
+      /**
+       * <code>.monitoring.KpiId kpi_id = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
+                  getKpiId(),
+                  getParentForChildren(),
+                  isClean());
+          kpiId_ = null;
+        }
+        return kpiIdBuilder_;
+      }
+
+      private java.lang.Object timestamp_ = "";
+      /**
+       * <code>string timestamp = 2;</code>
+       * @return The timestamp.
+       */
+      public java.lang.String getTimestamp() {
+        java.lang.Object ref = timestamp_;
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          timestamp_ = s;
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>string timestamp = 2;</code>
+       * @return The bytes for timestamp.
+       */
+      public com.google.protobuf.ByteString
+          getTimestampBytes() {
+        java.lang.Object ref = timestamp_;
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          timestamp_ = b;
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string timestamp = 2;</code>
+       * @param value The timestamp to set.
+       * @return This builder for chaining.
+       */
+      public Builder setTimestamp(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  
+        timestamp_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string timestamp = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearTimestamp() {
+        
+        timestamp_ = getDefaultInstance().getTimestamp();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string timestamp = 2;</code>
+       * @param value The bytes for timestamp to set.
+       * @return This builder for chaining.
+       */
+      public Builder setTimestampBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        
+        timestamp_ = value;
+        onChanged();
+        return this;
+      }
+
+      private monitoring.Monitoring.KpiValue kpiValue_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiValueBuilder_;
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 4;</code>
+       * @return Whether the kpiValue field is set.
+       */
+      public boolean hasKpiValue() {
+        return kpiValueBuilder_ != null || kpiValue_ != null;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 4;</code>
+       * @return The kpiValue.
+       */
+      public monitoring.Monitoring.KpiValue getKpiValue() {
+        if (kpiValueBuilder_ == null) {
+          return kpiValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+        } else {
+          return kpiValueBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 4;</code>
+       */
+      public Builder setKpiValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiValueBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          kpiValue_ = value;
+          onChanged();
+        } else {
+          kpiValueBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 4;</code>
+       */
+      public Builder setKpiValue(
+          monitoring.Monitoring.KpiValue.Builder builderForValue) {
+        if (kpiValueBuilder_ == null) {
+          kpiValue_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiValueBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 4;</code>
+       */
+      public Builder mergeKpiValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiValueBuilder_ == null) {
+          if (kpiValue_ != null) {
+            kpiValue_ =
+              monitoring.Monitoring.KpiValue.newBuilder(kpiValue_).mergeFrom(value).buildPartial();
+          } else {
+            kpiValue_ = value;
+          }
+          onChanged();
+        } else {
+          kpiValueBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 4;</code>
+       */
+      public Builder clearKpiValue() {
+        if (kpiValueBuilder_ == null) {
+          kpiValue_ = null;
+          onChanged();
+        } else {
+          kpiValue_ = null;
+          kpiValueBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 4;</code>
+       */
+      public monitoring.Monitoring.KpiValue.Builder getKpiValueBuilder() {
+        
+        onChanged();
+        return getKpiValueFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 4;</code>
+       */
+      public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
+        if (kpiValueBuilder_ != null) {
+          return kpiValueBuilder_.getMessageOrBuilder();
+        } else {
+          return kpiValue_ == null ?
+              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+        }
+      }
+      /**
+       * <code>.monitoring.KpiValue kpi_value = 4;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> 
+          getKpiValueFieldBuilder() {
+        if (kpiValueBuilder_ == null) {
+          kpiValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
+                  getKpiValue(),
+                  getParentForChildren(),
+                  isClean());
+          kpiValue_ = null;
+        }
+        return kpiValueBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:monitoring.Kpi)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.Kpi)
+    private static final monitoring.Monitoring.Kpi DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.Kpi();
+    }
+
+    public static monitoring.Monitoring.Kpi getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<Kpi>
+        PARSER = new com.google.protobuf.AbstractParser<Kpi>() {
+      @java.lang.Override
+      public Kpi parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new Kpi(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<Kpi> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<Kpi> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.Kpi getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface KpiValueOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiValue)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>uint32 intVal = 1;</code>
+     * @return Whether the intVal field is set.
+     */
+    boolean hasIntVal();
+    /**
+     * <code>uint32 intVal = 1;</code>
+     * @return The intVal.
+     */
+    int getIntVal();
+
+    /**
+     * <code>float floatVal = 2;</code>
+     * @return Whether the floatVal field is set.
+     */
+    boolean hasFloatVal();
+    /**
+     * <code>float floatVal = 2;</code>
+     * @return The floatVal.
+     */
+    float getFloatVal();
+
+    /**
+     * <code>string stringVal = 3;</code>
+     * @return Whether the stringVal field is set.
+     */
+    boolean hasStringVal();
+    /**
+     * <code>string stringVal = 3;</code>
+     * @return The stringVal.
+     */
+    java.lang.String getStringVal();
+    /**
+     * <code>string stringVal = 3;</code>
+     * @return The bytes for stringVal.
+     */
+    com.google.protobuf.ByteString
+        getStringValBytes();
+
+    /**
+     * <code>bool boolVal = 4;</code>
+     * @return Whether the boolVal field is set.
+     */
+    boolean hasBoolVal();
+    /**
+     * <code>bool boolVal = 4;</code>
+     * @return The boolVal.
+     */
+    boolean getBoolVal();
+
+    public monitoring.Monitoring.KpiValue.ValueCase getValueCase();
+  }
+  /**
+   * Protobuf type {@code monitoring.KpiValue}
+   */
+  public static final class KpiValue extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:monitoring.KpiValue)
+      KpiValueOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use KpiValue.newBuilder() to construct.
+    private KpiValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private KpiValue() {
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new KpiValue();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private KpiValue(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 8: {
+              valueCase_ = 1;
+              value_ = input.readUInt32();
+              break;
+            }
+            case 21: {
+              valueCase_ = 2;
+              value_ = input.readFloat();
+              break;
+            }
+            case 26: {
+              java.lang.String s = input.readStringRequireUtf8();
+              valueCase_ = 3;
+              value_ = s;
+              break;
+            }
+            case 32: {
+              valueCase_ = 4;
+              value_ = input.readBool();
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiValue_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiValue_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              monitoring.Monitoring.KpiValue.class, monitoring.Monitoring.KpiValue.Builder.class);
+    }
+
+    private int valueCase_ = 0;
+    private java.lang.Object value_;
+    public enum ValueCase
+        implements com.google.protobuf.Internal.EnumLite,
+            com.google.protobuf.AbstractMessage.InternalOneOfEnum {
+      INTVAL(1),
+      FLOATVAL(2),
+      STRINGVAL(3),
+      BOOLVAL(4),
+      VALUE_NOT_SET(0);
+      private final int value;
+      private ValueCase(int value) {
+        this.value = value;
+      }
+      /**
+       * @param value The number of the enum to look for.
+       * @return The enum associated with the given number.
+       * @deprecated Use {@link #forNumber(int)} instead.
+       */
+      @java.lang.Deprecated
+      public static ValueCase valueOf(int value) {
+        return forNumber(value);
+      }
+
+      public static ValueCase forNumber(int value) {
+        switch (value) {
+          case 1: return INTVAL;
+          case 2: return FLOATVAL;
+          case 3: return STRINGVAL;
+          case 4: return BOOLVAL;
+          case 0: return VALUE_NOT_SET;
+          default: return null;
+        }
+      }
+      public int getNumber() {
+        return this.value;
+      }
+    };
+
+    public ValueCase
+    getValueCase() {
+      return ValueCase.forNumber(
+          valueCase_);
+    }
+
+    public static final int INTVAL_FIELD_NUMBER = 1;
+    /**
+     * <code>uint32 intVal = 1;</code>
+     * @return Whether the intVal field is set.
+     */
+    @java.lang.Override
+    public boolean hasIntVal() {
+      return valueCase_ == 1;
+    }
+    /**
+     * <code>uint32 intVal = 1;</code>
+     * @return The intVal.
+     */
+    @java.lang.Override
+    public int getIntVal() {
+      if (valueCase_ == 1) {
+        return (java.lang.Integer) value_;
+      }
+      return 0;
+    }
+
+    public static final int FLOATVAL_FIELD_NUMBER = 2;
+    /**
+     * <code>float floatVal = 2;</code>
+     * @return Whether the floatVal field is set.
+     */
+    @java.lang.Override
+    public boolean hasFloatVal() {
+      return valueCase_ == 2;
+    }
+    /**
+     * <code>float floatVal = 2;</code>
+     * @return The floatVal.
+     */
+    @java.lang.Override
+    public float getFloatVal() {
+      if (valueCase_ == 2) {
+        return (java.lang.Float) value_;
+      }
+      return 0F;
+    }
+
+    public static final int STRINGVAL_FIELD_NUMBER = 3;
+    /**
+     * <code>string stringVal = 3;</code>
+     * @return Whether the stringVal field is set.
+     */
+    public boolean hasStringVal() {
+      return valueCase_ == 3;
+    }
+    /**
+     * <code>string stringVal = 3;</code>
+     * @return The stringVal.
+     */
+    public java.lang.String getStringVal() {
+      java.lang.Object ref = "";
+      if (valueCase_ == 3) {
+        ref = value_;
+      }
+      if (ref instanceof java.lang.String) {
+        return (java.lang.String) ref;
+      } else {
+        com.google.protobuf.ByteString bs = 
+            (com.google.protobuf.ByteString) ref;
+        java.lang.String s = bs.toStringUtf8();
+        if (valueCase_ == 3) {
+          value_ = s;
+        }
+        return s;
+      }
+    }
+    /**
+     * <code>string stringVal = 3;</code>
+     * @return The bytes for stringVal.
+     */
+    public com.google.protobuf.ByteString
+        getStringValBytes() {
+      java.lang.Object ref = "";
+      if (valueCase_ == 3) {
+        ref = value_;
+      }
+      if (ref instanceof java.lang.String) {
+        com.google.protobuf.ByteString b = 
+            com.google.protobuf.ByteString.copyFromUtf8(
+                (java.lang.String) ref);
+        if (valueCase_ == 3) {
+          value_ = b;
+        }
+        return b;
+      } else {
+        return (com.google.protobuf.ByteString) ref;
+      }
+    }
+
+    public static final int BOOLVAL_FIELD_NUMBER = 4;
+    /**
+     * <code>bool boolVal = 4;</code>
+     * @return Whether the boolVal field is set.
+     */
+    @java.lang.Override
+    public boolean hasBoolVal() {
+      return valueCase_ == 4;
+    }
+    /**
+     * <code>bool boolVal = 4;</code>
+     * @return The boolVal.
+     */
+    @java.lang.Override
+    public boolean getBoolVal() {
+      if (valueCase_ == 4) {
+        return (java.lang.Boolean) value_;
+      }
+      return false;
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (valueCase_ == 1) {
+        output.writeUInt32(
+            1, (int)((java.lang.Integer) value_));
+      }
+      if (valueCase_ == 2) {
+        output.writeFloat(
+            2, (float)((java.lang.Float) value_));
+      }
+      if (valueCase_ == 3) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 3, value_);
+      }
+      if (valueCase_ == 4) {
+        output.writeBool(
+            4, (boolean)((java.lang.Boolean) value_));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (valueCase_ == 1) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(
+              1, (int)((java.lang.Integer) value_));
+      }
+      if (valueCase_ == 2) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeFloatSize(
+              2, (float)((java.lang.Float) value_));
+      }
+      if (valueCase_ == 3) {
+        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(3, value_);
+      }
+      if (valueCase_ == 4) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeBoolSize(
+              4, (boolean)((java.lang.Boolean) value_));
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof monitoring.Monitoring.KpiValue)) {
+        return super.equals(obj);
+      }
+      monitoring.Monitoring.KpiValue other = (monitoring.Monitoring.KpiValue) obj;
+
+      if (!getValueCase().equals(other.getValueCase())) return false;
+      switch (valueCase_) {
+        case 1:
+          if (getIntVal()
+              != other.getIntVal()) return false;
+          break;
+        case 2:
+          if (java.lang.Float.floatToIntBits(getFloatVal())
+              != java.lang.Float.floatToIntBits(
+                  other.getFloatVal())) return false;
+          break;
+        case 3:
+          if (!getStringVal()
+              .equals(other.getStringVal())) return false;
+          break;
+        case 4:
+          if (getBoolVal()
+              != other.getBoolVal()) return false;
+          break;
+        case 0:
+        default:
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      switch (valueCase_) {
+        case 1:
+          hash = (37 * hash) + INTVAL_FIELD_NUMBER;
+          hash = (53 * hash) + getIntVal();
+          break;
+        case 2:
+          hash = (37 * hash) + FLOATVAL_FIELD_NUMBER;
+          hash = (53 * hash) + java.lang.Float.floatToIntBits(
+              getFloatVal());
+          break;
+        case 3:
+          hash = (37 * hash) + STRINGVAL_FIELD_NUMBER;
+          hash = (53 * hash) + getStringVal().hashCode();
+          break;
+        case 4:
+          hash = (37 * hash) + BOOLVAL_FIELD_NUMBER;
+          hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(
+              getBoolVal());
+          break;
+        case 0:
+        default:
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static monitoring.Monitoring.KpiValue parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiValue parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiValue parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiValue parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiValue parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiValue parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiValue parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiValue parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiValue parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiValue parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiValue parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiValue parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(monitoring.Monitoring.KpiValue prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code monitoring.KpiValue}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiValue)
+        monitoring.Monitoring.KpiValueOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiValue_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiValue_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.KpiValue.class, monitoring.Monitoring.KpiValue.Builder.class);
+      }
+
+      // Construct using monitoring.Monitoring.KpiValue.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        valueCase_ = 0;
+        value_ = null;
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiValue_descriptor;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiValue.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiValue build() {
+        monitoring.Monitoring.KpiValue result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiValue buildPartial() {
+        monitoring.Monitoring.KpiValue result = new monitoring.Monitoring.KpiValue(this);
+        if (valueCase_ == 1) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 2) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 3) {
+          result.value_ = value_;
+        }
+        if (valueCase_ == 4) {
+          result.value_ = value_;
+        }
+        result.valueCase_ = valueCase_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.KpiValue) {
+          return mergeFrom((monitoring.Monitoring.KpiValue)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(monitoring.Monitoring.KpiValue other) {
+        if (other == monitoring.Monitoring.KpiValue.getDefaultInstance()) return this;
+        switch (other.getValueCase()) {
+          case INTVAL: {
+            setIntVal(other.getIntVal());
+            break;
+          }
+          case FLOATVAL: {
+            setFloatVal(other.getFloatVal());
+            break;
+          }
+          case STRINGVAL: {
+            valueCase_ = 3;
+            value_ = other.value_;
+            onChanged();
+            break;
+          }
+          case BOOLVAL: {
+            setBoolVal(other.getBoolVal());
+            break;
+          }
+          case VALUE_NOT_SET: {
+            break;
+          }
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.KpiValue parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.KpiValue) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int valueCase_ = 0;
+      private java.lang.Object value_;
+      public ValueCase
+          getValueCase() {
+        return ValueCase.forNumber(
+            valueCase_);
+      }
+
+      public Builder clearValue() {
+        valueCase_ = 0;
+        value_ = null;
+        onChanged();
+        return this;
+      }
+
+
+      /**
+       * <code>uint32 intVal = 1;</code>
+       * @return Whether the intVal field is set.
+       */
+      public boolean hasIntVal() {
+        return valueCase_ == 1;
+      }
+      /**
+       * <code>uint32 intVal = 1;</code>
+       * @return The intVal.
+       */
+      public int getIntVal() {
+        if (valueCase_ == 1) {
+          return (java.lang.Integer) value_;
+        }
+        return 0;
+      }
+      /**
+       * <code>uint32 intVal = 1;</code>
+       * @param value The intVal to set.
+       * @return This builder for chaining.
+       */
+      public Builder setIntVal(int value) {
+        valueCase_ = 1;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>uint32 intVal = 1;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearIntVal() {
+        if (valueCase_ == 1) {
+          valueCase_ = 0;
+          value_ = null;
+          onChanged();
+        }
+        return this;
+      }
+
+      /**
+       * <code>float floatVal = 2;</code>
+       * @return Whether the floatVal field is set.
+       */
+      public boolean hasFloatVal() {
+        return valueCase_ == 2;
+      }
+      /**
+       * <code>float floatVal = 2;</code>
+       * @return The floatVal.
+       */
+      public float getFloatVal() {
+        if (valueCase_ == 2) {
+          return (java.lang.Float) value_;
+        }
+        return 0F;
+      }
+      /**
+       * <code>float floatVal = 2;</code>
+       * @param value The floatVal to set.
+       * @return This builder for chaining.
+       */
+      public Builder setFloatVal(float value) {
+        valueCase_ = 2;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>float floatVal = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearFloatVal() {
+        if (valueCase_ == 2) {
+          valueCase_ = 0;
+          value_ = null;
+          onChanged();
+        }
+        return this;
+      }
+
+      /**
+       * <code>string stringVal = 3;</code>
+       * @return Whether the stringVal field is set.
+       */
+      @java.lang.Override
+      public boolean hasStringVal() {
+        return valueCase_ == 3;
+      }
+      /**
+       * <code>string stringVal = 3;</code>
+       * @return The stringVal.
+       */
+      @java.lang.Override
+      public java.lang.String getStringVal() {
+        java.lang.Object ref = "";
+        if (valueCase_ == 3) {
+          ref = value_;
+        }
+        if (!(ref instanceof java.lang.String)) {
+          com.google.protobuf.ByteString bs =
+              (com.google.protobuf.ByteString) ref;
+          java.lang.String s = bs.toStringUtf8();
+          if (valueCase_ == 3) {
+            value_ = s;
+          }
+          return s;
+        } else {
+          return (java.lang.String) ref;
+        }
+      }
+      /**
+       * <code>string stringVal = 3;</code>
+       * @return The bytes for stringVal.
+       */
+      @java.lang.Override
+      public com.google.protobuf.ByteString
+          getStringValBytes() {
+        java.lang.Object ref = "";
+        if (valueCase_ == 3) {
+          ref = value_;
+        }
+        if (ref instanceof String) {
+          com.google.protobuf.ByteString b = 
+              com.google.protobuf.ByteString.copyFromUtf8(
+                  (java.lang.String) ref);
+          if (valueCase_ == 3) {
+            value_ = b;
+          }
+          return b;
+        } else {
+          return (com.google.protobuf.ByteString) ref;
+        }
+      }
+      /**
+       * <code>string stringVal = 3;</code>
+       * @param value The stringVal to set.
+       * @return This builder for chaining.
+       */
+      public Builder setStringVal(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  valueCase_ = 3;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>string stringVal = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearStringVal() {
+        if (valueCase_ == 3) {
+          valueCase_ = 0;
+          value_ = null;
+          onChanged();
+        }
+        return this;
+      }
+      /**
+       * <code>string stringVal = 3;</code>
+       * @param value The bytes for stringVal to set.
+       * @return This builder for chaining.
+       */
+      public Builder setStringValBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        valueCase_ = 3;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+
+      /**
+       * <code>bool boolVal = 4;</code>
+       * @return Whether the boolVal field is set.
+       */
+      public boolean hasBoolVal() {
+        return valueCase_ == 4;
+      }
+      /**
+       * <code>bool boolVal = 4;</code>
+       * @return The boolVal.
+       */
+      public boolean getBoolVal() {
+        if (valueCase_ == 4) {
+          return (java.lang.Boolean) value_;
+        }
+        return false;
+      }
+      /**
+       * <code>bool boolVal = 4;</code>
+       * @param value The boolVal to set.
+       * @return This builder for chaining.
+       */
+      public Builder setBoolVal(boolean value) {
+        valueCase_ = 4;
+        value_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>bool boolVal = 4;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearBoolVal() {
+        if (valueCase_ == 4) {
+          valueCase_ = 0;
+          value_ = null;
+          onChanged();
+        }
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiValue)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.KpiValue)
+    private static final monitoring.Monitoring.KpiValue DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiValue();
+    }
+
+    public static monitoring.Monitoring.KpiValue getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<KpiValue>
+        PARSER = new com.google.protobuf.AbstractParser<KpiValue>() {
+      @java.lang.Override
+      public KpiValue parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new KpiValue(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<KpiValue> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<KpiValue> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValue getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface KpiListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:monitoring.KpiList)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    java.util.List<monitoring.Monitoring.Kpi> 
+        getKpiListList();
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    monitoring.Monitoring.Kpi getKpiList(int index);
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    int getKpiListCount();
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
+        getKpiListOrBuilderList();
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+        int index);
+  }
+  /**
+   * Protobuf type {@code monitoring.KpiList}
+   */
+  public static final class KpiList extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:monitoring.KpiList)
+      KpiListOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use KpiList.newBuilder() to construct.
+    private KpiList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private KpiList() {
+      kpiList_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new KpiList();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private KpiList(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                kpiList_ = new java.util.ArrayList<monitoring.Monitoring.Kpi>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              kpiList_.add(
+                  input.readMessage(monitoring.Monitoring.Kpi.parser(), extensionRegistry));
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return monitoring.Monitoring.internal_static_monitoring_KpiList_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              monitoring.Monitoring.KpiList.class, monitoring.Monitoring.KpiList.Builder.class);
+    }
+
+    public static final int KPI_LIST_FIELD_NUMBER = 1;
+    private java.util.List<monitoring.Monitoring.Kpi> kpiList_;
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
+      return kpiList_;
+    }
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
+        getKpiListOrBuilderList() {
+      return kpiList_;
+    }
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    @java.lang.Override
+    public int getKpiListCount() {
+      return kpiList_.size();
+    }
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.Kpi getKpiList(int index) {
+      return kpiList_.get(index);
+    }
+    /**
+     * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+        int index) {
+      return kpiList_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < kpiList_.size(); i++) {
+        output.writeMessage(1, kpiList_.get(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < kpiList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, kpiList_.get(i));
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof monitoring.Monitoring.KpiList)) {
+        return super.equals(obj);
+      }
+      monitoring.Monitoring.KpiList other = (monitoring.Monitoring.KpiList) obj;
+
+      if (!getKpiListList()
+          .equals(other.getKpiListList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getKpiListCount() > 0) {
+        hash = (37 * hash) + KPI_LIST_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiListList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static monitoring.Monitoring.KpiList parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiList parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiList parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiList parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiList parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static monitoring.Monitoring.KpiList parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiList parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiList parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiList parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiList parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static monitoring.Monitoring.KpiList parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static monitoring.Monitoring.KpiList parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(monitoring.Monitoring.KpiList prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * Protobuf type {@code monitoring.KpiList}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:monitoring.KpiList)
+        monitoring.Monitoring.KpiListOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiList_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                monitoring.Monitoring.KpiList.class, monitoring.Monitoring.KpiList.Builder.class);
+      }
+
+      // Construct using monitoring.Monitoring.KpiList.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getKpiListFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (kpiListBuilder_ == null) {
+          kpiList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          kpiListBuilder_.clear();
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return monitoring.Monitoring.internal_static_monitoring_KpiList_descriptor;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
+        return monitoring.Monitoring.KpiList.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiList build() {
+        monitoring.Monitoring.KpiList result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public monitoring.Monitoring.KpiList buildPartial() {
+        monitoring.Monitoring.KpiList result = new monitoring.Monitoring.KpiList(this);
+        int from_bitField0_ = bitField0_;
+        if (kpiListBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            kpiList_ = java.util.Collections.unmodifiableList(kpiList_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.kpiList_ = kpiList_;
+        } else {
+          result.kpiList_ = kpiListBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof monitoring.Monitoring.KpiList) {
+          return mergeFrom((monitoring.Monitoring.KpiList)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(monitoring.Monitoring.KpiList other) {
+        if (other == monitoring.Monitoring.KpiList.getDefaultInstance()) return this;
+        if (kpiListBuilder_ == null) {
+          if (!other.kpiList_.isEmpty()) {
+            if (kpiList_.isEmpty()) {
+              kpiList_ = other.kpiList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureKpiListIsMutable();
+              kpiList_.addAll(other.kpiList_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.kpiList_.isEmpty()) {
+            if (kpiListBuilder_.isEmpty()) {
+              kpiListBuilder_.dispose();
+              kpiListBuilder_ = null;
+              kpiList_ = other.kpiList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              kpiListBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getKpiListFieldBuilder() : null;
+            } else {
+              kpiListBuilder_.addAllMessages(other.kpiList_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        monitoring.Monitoring.KpiList parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (monitoring.Monitoring.KpiList) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private java.util.List<monitoring.Monitoring.Kpi> kpiList_ =
+        java.util.Collections.emptyList();
+      private void ensureKpiListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          kpiList_ = new java.util.ArrayList<monitoring.Monitoring.Kpi>(kpiList_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.Kpi, monitoring.Monitoring.Kpi.Builder, monitoring.Monitoring.KpiOrBuilder> kpiListBuilder_;
+
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public java.util.List<monitoring.Monitoring.Kpi> getKpiListList() {
+        if (kpiListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(kpiList_);
+        } else {
+          return kpiListBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public int getKpiListCount() {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.size();
+        } else {
+          return kpiListBuilder_.getCount();
+        }
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public monitoring.Monitoring.Kpi getKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);
+        } else {
+          return kpiListBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public Builder setKpiList(
+          int index, monitoring.Monitoring.Kpi value) {
+        if (kpiListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiListIsMutable();
+          kpiList_.set(index, value);
+          onChanged();
+        } else {
+          kpiListBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public Builder setKpiList(
+          int index, monitoring.Monitoring.Kpi.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiListBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public Builder addKpiList(monitoring.Monitoring.Kpi value) {
+        if (kpiListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiListIsMutable();
+          kpiList_.add(value);
+          onChanged();
+        } else {
+          kpiListBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public Builder addKpiList(
+          int index, monitoring.Monitoring.Kpi value) {
+        if (kpiListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureKpiListIsMutable();
+          kpiList_.add(index, value);
+          onChanged();
+        } else {
+          kpiListBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public Builder addKpiList(
+          monitoring.Monitoring.Kpi.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.add(builderForValue.build());
+          onChanged();
+        } else {
+          kpiListBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public Builder addKpiList(
+          int index, monitoring.Monitoring.Kpi.Builder builderForValue) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          kpiListBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public Builder addAllKpiList(
+          java.lang.Iterable<? extends monitoring.Monitoring.Kpi> values) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, kpiList_);
+          onChanged();
+        } else {
+          kpiListBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public Builder clearKpiList() {
+        if (kpiListBuilder_ == null) {
+          kpiList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          kpiListBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public Builder removeKpiList(int index) {
+        if (kpiListBuilder_ == null) {
+          ensureKpiListIsMutable();
+          kpiList_.remove(index);
+          onChanged();
+        } else {
+          kpiListBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public monitoring.Monitoring.Kpi.Builder getKpiListBuilder(
+          int index) {
+        return getKpiListFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public monitoring.Monitoring.KpiOrBuilder getKpiListOrBuilder(
+          int index) {
+        if (kpiListBuilder_ == null) {
+          return kpiList_.get(index);  } else {
+          return kpiListBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public java.util.List<? extends monitoring.Monitoring.KpiOrBuilder> 
+           getKpiListOrBuilderList() {
+        if (kpiListBuilder_ != null) {
+          return kpiListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(kpiList_);
+        }
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public monitoring.Monitoring.Kpi.Builder addKpiListBuilder() {
+        return getKpiListFieldBuilder().addBuilder(
+            monitoring.Monitoring.Kpi.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public monitoring.Monitoring.Kpi.Builder addKpiListBuilder(
+          int index) {
+        return getKpiListFieldBuilder().addBuilder(
+            index, monitoring.Monitoring.Kpi.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .monitoring.Kpi kpi_list = 1;</code>
+       */
+      public java.util.List<monitoring.Monitoring.Kpi.Builder> 
+           getKpiListBuilderList() {
+        return getKpiListFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          monitoring.Monitoring.Kpi, monitoring.Monitoring.Kpi.Builder, monitoring.Monitoring.KpiOrBuilder> 
+          getKpiListFieldBuilder() {
+        if (kpiListBuilder_ == null) {
+          kpiListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              monitoring.Monitoring.Kpi, monitoring.Monitoring.Kpi.Builder, monitoring.Monitoring.KpiOrBuilder>(
+                  kpiList_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          kpiList_ = null;
+        }
+        return kpiListBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:monitoring.KpiList)
+    }
+
+    // @@protoc_insertion_point(class_scope:monitoring.KpiList)
+    private static final monitoring.Monitoring.KpiList DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new monitoring.Monitoring.KpiList();
+    }
+
+    public static monitoring.Monitoring.KpiList getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<KpiList>
+        PARSER = new com.google.protobuf.AbstractParser<KpiList>() {
+      @java.lang.Override
+      public KpiList parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new KpiList(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<KpiList> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<KpiList> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public monitoring.Monitoring.KpiList getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_monitoring_KpiDescriptor_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_monitoring_KpiDescriptor_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_monitoring_MonitorKpiRequest_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_monitoring_MonitorKpiRequest_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_monitoring_KpiId_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_monitoring_KpiId_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_monitoring_Kpi_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_monitoring_Kpi_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_monitoring_KpiValue_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_monitoring_KpiValue_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_monitoring_KpiList_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_monitoring_KpiList_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\020monitoring.proto\022\nmonitoring\032\rcontext." +
+      "proto\032\026kpi_sample_types.proto\"\332\001\n\rKpiDes" +
+      "criptor\022\027\n\017kpi_description\030\001 \001(\t\0228\n\017kpi_" +
+      "sample_type\030\002 \001(\0162\037.kpi_sample_types.Kpi" +
+      "SampleType\022$\n\tdevice_id\030\003 \001(\0132\021.context." +
+      "DeviceId\022(\n\013endpoint_id\030\004 \001(\0132\023.context." +
+      "EndPointId\022&\n\nservice_id\030\005 \001(\0132\022.context" +
+      ".ServiceId\"p\n\021MonitorKpiRequest\022!\n\006kpi_i" +
+      "d\030\001 \001(\0132\021.monitoring.KpiId\022\033\n\023sampling_d" +
+      "uration_s\030\002 \001(\002\022\033\n\023sampling_interval_s\030\003" +
+      " \001(\002\"&\n\005KpiId\022\035\n\006kpi_id\030\001 \001(\0132\r.context." +
+      "Uuid\"d\n\003Kpi\022!\n\006kpi_id\030\001 \001(\0132\021.monitoring" +
+      ".KpiId\022\021\n\ttimestamp\030\002 \001(\t\022\'\n\tkpi_value\030\004" +
+      " \001(\0132\024.monitoring.KpiValue\"a\n\010KpiValue\022\020" +
+      "\n\006intVal\030\001 \001(\rH\000\022\022\n\010floatVal\030\002 \001(\002H\000\022\023\n\t" +
+      "stringVal\030\003 \001(\tH\000\022\021\n\007boolVal\030\004 \001(\010H\000B\007\n\005" +
+      "value\",\n\007KpiList\022!\n\010kpi_list\030\001 \003(\0132\017.mon" +
+      "itoring.Kpi2\363\002\n\021MonitoringService\022;\n\tCre" +
+      "ateKpi\022\031.monitoring.KpiDescriptor\032\021.moni" +
+      "toring.KpiId\"\000\022B\n\020GetKpiDescriptor\022\021.mon" +
+      "itoring.KpiId\032\031.monitoring.KpiDescriptor" +
+      "\"\000\022/\n\nIncludeKpi\022\017.monitoring.Kpi\032\016.cont" +
+      "ext.Empty\"\000\022=\n\nMonitorKpi\022\035.monitoring.M" +
+      "onitorKpiRequest\032\016.context.Empty\"\000\0226\n\014Ge" +
+      "tStreamKpi\022\021.monitoring.KpiId\032\017.monitori" +
+      "ng.Kpi\"\0000\001\0225\n\rGetInstantKpi\022\021.monitoring" +
+      ".KpiId\032\017.monitoring.Kpi\"\000b\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          context.ContextOuterClass.getDescriptor(),
+          kpi_sample_types.KpiSampleTypes.getDescriptor(),
+        });
+    internal_static_monitoring_KpiDescriptor_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_monitoring_KpiDescriptor_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_monitoring_KpiDescriptor_descriptor,
+        new java.lang.String[] { "KpiDescription", "KpiSampleType", "DeviceId", "EndpointId", "ServiceId", });
+    internal_static_monitoring_MonitorKpiRequest_descriptor =
+      getDescriptor().getMessageTypes().get(1);
+    internal_static_monitoring_MonitorKpiRequest_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_monitoring_MonitorKpiRequest_descriptor,
+        new java.lang.String[] { "KpiId", "SamplingDurationS", "SamplingIntervalS", });
+    internal_static_monitoring_KpiId_descriptor =
+      getDescriptor().getMessageTypes().get(2);
+    internal_static_monitoring_KpiId_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_monitoring_KpiId_descriptor,
+        new java.lang.String[] { "KpiId", });
+    internal_static_monitoring_Kpi_descriptor =
+      getDescriptor().getMessageTypes().get(3);
+    internal_static_monitoring_Kpi_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_monitoring_Kpi_descriptor,
+        new java.lang.String[] { "KpiId", "Timestamp", "KpiValue", });
+    internal_static_monitoring_KpiValue_descriptor =
+      getDescriptor().getMessageTypes().get(4);
+    internal_static_monitoring_KpiValue_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_monitoring_KpiValue_descriptor,
+        new java.lang.String[] { "IntVal", "FloatVal", "StringVal", "BoolVal", "Value", });
+    internal_static_monitoring_KpiList_descriptor =
+      getDescriptor().getMessageTypes().get(5);
+    internal_static_monitoring_KpiList_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_monitoring_KpiList_descriptor,
+        new java.lang.String[] { "KpiList", });
+    context.ContextOuterClass.getDescriptor();
+    kpi_sample_types.KpiSampleTypes.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/policy/target/generated-sources/grpc/monitoring/MonitoringService.java b/src/policy/target/generated-sources/grpc/monitoring/MonitoringService.java
new file mode 100644
index 000000000..480e19312
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/monitoring/MonitoringService.java
@@ -0,0 +1,26 @@
+package monitoring;
+
+import io.quarkus.grpc.runtime.MutinyService;
+
+@javax.annotation.Generated(
+value = "by Mutiny Grpc generator",
+comments = "Source: monitoring.proto")
+public interface MonitoringService extends MutinyService {
+
+    
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request);
+    
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> monitorKpi(monitoring.Monitoring.MonitorKpiRequest request);
+    
+    io.smallrye.mutiny.Uni<monitoring.Monitoring.Kpi> getInstantKpi(monitoring.Monitoring.KpiId request);
+    
+    
+    io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request);
+    
+    
+
+}
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java
new file mode 100644
index 000000000..b0b2f5abd
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceBean.java
@@ -0,0 +1,68 @@
+package monitoring;
+
+import io.grpc.BindableService;
+import io.quarkus.grpc.GrpcService;
+import io.quarkus.grpc.runtime.MutinyBean;
+
+@javax.annotation.Generated(
+value = "by Mutiny Grpc generator",
+comments = "Source: monitoring.proto")
+public class MonitoringServiceBean extends MutinyMonitoringServiceGrpc.MonitoringServiceImplBase implements BindableService, MutinyBean {
+
+    private final MonitoringService delegate;
+
+    MonitoringServiceBean(@GrpcService MonitoringService delegate) {
+       this.delegate = delegate;
+    }
+
+    @Override
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
+       try {
+         return delegate.createKpi(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
+       try {
+         return delegate.getKpiDescriptor(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
+       try {
+         return delegate.includeKpi(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> monitorKpi(monitoring.Monitoring.MonitorKpiRequest request) {
+       try {
+         return delegate.monitorKpi(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.Kpi> getInstantKpi(monitoring.Monitoring.KpiId request) {
+       try {
+         return delegate.getInstantKpi(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+
+    @Override
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request) {
+       try {
+         return delegate.getStreamKpi(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+
+}
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java
new file mode 100644
index 000000000..293a7c418
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceClient.java
@@ -0,0 +1,49 @@
+package monitoring;
+
+import java.util.function.BiFunction;
+
+import io.quarkus.grpc.runtime.MutinyClient;
+
+@javax.annotation.Generated(
+value = "by Mutiny Grpc generator",
+comments = "Source: monitoring.proto")
+public class MonitoringServiceClient implements MonitoringService, MutinyClient<MutinyMonitoringServiceGrpc.MutinyMonitoringServiceStub> {
+
+    private final MutinyMonitoringServiceGrpc.MutinyMonitoringServiceStub stub;
+
+    public MonitoringServiceClient(String name, io.grpc.Channel channel, BiFunction<String, MutinyMonitoringServiceGrpc.MutinyMonitoringServiceStub, MutinyMonitoringServiceGrpc.MutinyMonitoringServiceStub> stubConfigurator) {
+       this.stub = stubConfigurator.apply(name,MutinyMonitoringServiceGrpc.newMutinyStub(channel));
+    }
+
+    @Override
+    public MutinyMonitoringServiceGrpc.MutinyMonitoringServiceStub getStub() {
+       return stub;
+    }
+
+    @Override
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
+       return stub.createKpi(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
+       return stub.getKpiDescriptor(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
+       return stub.includeKpi(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> monitorKpi(monitoring.Monitoring.MonitorKpiRequest request) {
+       return stub.monitorKpi(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<monitoring.Monitoring.Kpi> getInstantKpi(monitoring.Monitoring.KpiId request) {
+       return stub.getInstantKpi(request);
+    }
+
+    @Override
+    public io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request) {
+       return stub.getStreamKpi(request);
+    }
+
+}
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java
new file mode 100644
index 000000000..7749c322a
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/monitoring/MonitoringServiceGrpc.java
@@ -0,0 +1,638 @@
+package monitoring;
+
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+
+/**
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler (version 1.38.1)",
+    comments = "Source: monitoring.proto")
+public final class MonitoringServiceGrpc {
+
+  private MonitoringServiceGrpc() {}
+
+  public static final String SERVICE_NAME = "monitoring.MonitoringService";
+
+  // Static method descriptors that strictly reflect the proto.
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiDescriptor,
+      monitoring.Monitoring.KpiId> getCreateKpiMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "CreateKpi",
+      requestType = monitoring.Monitoring.KpiDescriptor.class,
+      responseType = monitoring.Monitoring.KpiId.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiDescriptor,
+      monitoring.Monitoring.KpiId> getCreateKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiId> getCreateKpiMethod;
+    if ((getCreateKpiMethod = MonitoringServiceGrpc.getCreateKpiMethod) == null) {
+      synchronized (MonitoringServiceGrpc.class) {
+        if ((getCreateKpiMethod = MonitoringServiceGrpc.getCreateKpiMethod) == null) {
+          MonitoringServiceGrpc.getCreateKpiMethod = getCreateKpiMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiDescriptor, monitoring.Monitoring.KpiId>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "CreateKpi"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.KpiDescriptor.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.KpiId.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("CreateKpi"))
+              .build();
+        }
+      }
+    }
+    return getCreateKpiMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      monitoring.Monitoring.KpiDescriptor> getGetKpiDescriptorMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "GetKpiDescriptor",
+      requestType = monitoring.Monitoring.KpiId.class,
+      responseType = monitoring.Monitoring.KpiDescriptor.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      monitoring.Monitoring.KpiDescriptor> getGetKpiDescriptorMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiDescriptor> getGetKpiDescriptorMethod;
+    if ((getGetKpiDescriptorMethod = MonitoringServiceGrpc.getGetKpiDescriptorMethod) == null) {
+      synchronized (MonitoringServiceGrpc.class) {
+        if ((getGetKpiDescriptorMethod = MonitoringServiceGrpc.getGetKpiDescriptorMethod) == null) {
+          MonitoringServiceGrpc.getGetKpiDescriptorMethod = getGetKpiDescriptorMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiDescriptor>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetKpiDescriptor"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.KpiId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.KpiDescriptor.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("GetKpiDescriptor"))
+              .build();
+        }
+      }
+    }
+    return getGetKpiDescriptorMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.Kpi,
+      context.ContextOuterClass.Empty> getIncludeKpiMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "IncludeKpi",
+      requestType = monitoring.Monitoring.Kpi.class,
+      responseType = context.ContextOuterClass.Empty.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.Kpi,
+      context.ContextOuterClass.Empty> getIncludeKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.Kpi, context.ContextOuterClass.Empty> getIncludeKpiMethod;
+    if ((getIncludeKpiMethod = MonitoringServiceGrpc.getIncludeKpiMethod) == null) {
+      synchronized (MonitoringServiceGrpc.class) {
+        if ((getIncludeKpiMethod = MonitoringServiceGrpc.getIncludeKpiMethod) == null) {
+          MonitoringServiceGrpc.getIncludeKpiMethod = getIncludeKpiMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.Kpi, context.ContextOuterClass.Empty>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "IncludeKpi"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.Kpi.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Empty.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("IncludeKpi"))
+              .build();
+        }
+      }
+    }
+    return getIncludeKpiMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.MonitorKpiRequest,
+      context.ContextOuterClass.Empty> getMonitorKpiMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "MonitorKpi",
+      requestType = monitoring.Monitoring.MonitorKpiRequest.class,
+      responseType = context.ContextOuterClass.Empty.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.MonitorKpiRequest,
+      context.ContextOuterClass.Empty> getMonitorKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.MonitorKpiRequest, context.ContextOuterClass.Empty> getMonitorKpiMethod;
+    if ((getMonitorKpiMethod = MonitoringServiceGrpc.getMonitorKpiMethod) == null) {
+      synchronized (MonitoringServiceGrpc.class) {
+        if ((getMonitorKpiMethod = MonitoringServiceGrpc.getMonitorKpiMethod) == null) {
+          MonitoringServiceGrpc.getMonitorKpiMethod = getMonitorKpiMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.MonitorKpiRequest, context.ContextOuterClass.Empty>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "MonitorKpi"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.MonitorKpiRequest.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Empty.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("MonitorKpi"))
+              .build();
+        }
+      }
+    }
+    return getMonitorKpiMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      monitoring.Monitoring.Kpi> getGetStreamKpiMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "GetStreamKpi",
+      requestType = monitoring.Monitoring.KpiId.class,
+      responseType = monitoring.Monitoring.Kpi.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      monitoring.Monitoring.Kpi> getGetStreamKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, monitoring.Monitoring.Kpi> getGetStreamKpiMethod;
+    if ((getGetStreamKpiMethod = MonitoringServiceGrpc.getGetStreamKpiMethod) == null) {
+      synchronized (MonitoringServiceGrpc.class) {
+        if ((getGetStreamKpiMethod = MonitoringServiceGrpc.getGetStreamKpiMethod) == null) {
+          MonitoringServiceGrpc.getGetStreamKpiMethod = getGetStreamKpiMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiId, monitoring.Monitoring.Kpi>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.SERVER_STREAMING)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetStreamKpi"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.KpiId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.Kpi.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("GetStreamKpi"))
+              .build();
+        }
+      }
+    }
+    return getGetStreamKpiMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      monitoring.Monitoring.Kpi> getGetInstantKpiMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "GetInstantKpi",
+      requestType = monitoring.Monitoring.KpiId.class,
+      responseType = monitoring.Monitoring.Kpi.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId,
+      monitoring.Monitoring.Kpi> getGetInstantKpiMethod() {
+    io.grpc.MethodDescriptor<monitoring.Monitoring.KpiId, monitoring.Monitoring.Kpi> getGetInstantKpiMethod;
+    if ((getGetInstantKpiMethod = MonitoringServiceGrpc.getGetInstantKpiMethod) == null) {
+      synchronized (MonitoringServiceGrpc.class) {
+        if ((getGetInstantKpiMethod = MonitoringServiceGrpc.getGetInstantKpiMethod) == null) {
+          MonitoringServiceGrpc.getGetInstantKpiMethod = getGetInstantKpiMethod =
+              io.grpc.MethodDescriptor.<monitoring.Monitoring.KpiId, monitoring.Monitoring.Kpi>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetInstantKpi"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.KpiId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  monitoring.Monitoring.Kpi.getDefaultInstance()))
+              .setSchemaDescriptor(new MonitoringServiceMethodDescriptorSupplier("GetInstantKpi"))
+              .build();
+        }
+      }
+    }
+    return getGetInstantKpiMethod;
+  }
+
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static MonitoringServiceStub newStub(io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<MonitoringServiceStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<MonitoringServiceStub>() {
+        @java.lang.Override
+        public MonitoringServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new MonitoringServiceStub(channel, callOptions);
+        }
+      };
+    return MonitoringServiceStub.newStub(factory, channel);
+  }
+
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static MonitoringServiceBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<MonitoringServiceBlockingStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<MonitoringServiceBlockingStub>() {
+        @java.lang.Override
+        public MonitoringServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new MonitoringServiceBlockingStub(channel, callOptions);
+        }
+      };
+    return MonitoringServiceBlockingStub.newStub(factory, channel);
+  }
+
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static MonitoringServiceFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<MonitoringServiceFutureStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<MonitoringServiceFutureStub>() {
+        @java.lang.Override
+        public MonitoringServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new MonitoringServiceFutureStub(channel, callOptions);
+        }
+      };
+    return MonitoringServiceFutureStub.newStub(factory, channel);
+  }
+
+  /**
+   */
+  public static abstract class MonitoringServiceImplBase implements io.grpc.BindableService {
+
+    /**
+     */
+    public void createKpi(monitoring.Monitoring.KpiDescriptor request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCreateKpiMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void getKpiDescriptor(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptor> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetKpiDescriptorMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void includeKpi(monitoring.Monitoring.Kpi request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getIncludeKpiMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void monitorKpi(monitoring.Monitoring.MonitorKpiRequest request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getMonitorKpiMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void getStreamKpi(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.Kpi> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetStreamKpiMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void getInstantKpi(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.Kpi> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetInstantKpiMethod(), responseObserver);
+    }
+
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getCreateKpiMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                monitoring.Monitoring.KpiDescriptor,
+                monitoring.Monitoring.KpiId>(
+                  this, METHODID_CREATE_KPI)))
+          .addMethod(
+            getGetKpiDescriptorMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                monitoring.Monitoring.KpiId,
+                monitoring.Monitoring.KpiDescriptor>(
+                  this, METHODID_GET_KPI_DESCRIPTOR)))
+          .addMethod(
+            getIncludeKpiMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                monitoring.Monitoring.Kpi,
+                context.ContextOuterClass.Empty>(
+                  this, METHODID_INCLUDE_KPI)))
+          .addMethod(
+            getMonitorKpiMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                monitoring.Monitoring.MonitorKpiRequest,
+                context.ContextOuterClass.Empty>(
+                  this, METHODID_MONITOR_KPI)))
+          .addMethod(
+            getGetStreamKpiMethod(),
+            io.grpc.stub.ServerCalls.asyncServerStreamingCall(
+              new MethodHandlers<
+                monitoring.Monitoring.KpiId,
+                monitoring.Monitoring.Kpi>(
+                  this, METHODID_GET_STREAM_KPI)))
+          .addMethod(
+            getGetInstantKpiMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                monitoring.Monitoring.KpiId,
+                monitoring.Monitoring.Kpi>(
+                  this, METHODID_GET_INSTANT_KPI)))
+          .build();
+    }
+  }
+
+  /**
+   */
+  public static final class MonitoringServiceStub extends io.grpc.stub.AbstractAsyncStub<MonitoringServiceStub> {
+    private MonitoringServiceStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected MonitoringServiceStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new MonitoringServiceStub(channel, callOptions);
+    }
+
+    /**
+     */
+    public void createKpi(monitoring.Monitoring.KpiDescriptor request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getCreateKpiMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void getKpiDescriptor(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptor> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getGetKpiDescriptorMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void includeKpi(monitoring.Monitoring.Kpi request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getIncludeKpiMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void monitorKpi(monitoring.Monitoring.MonitorKpiRequest request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getMonitorKpiMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void getStreamKpi(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.Kpi> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncServerStreamingCall(
+          getChannel().newCall(getGetStreamKpiMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void getInstantKpi(monitoring.Monitoring.KpiId request,
+        io.grpc.stub.StreamObserver<monitoring.Monitoring.Kpi> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getGetInstantKpiMethod(), getCallOptions()), request, responseObserver);
+    }
+  }
+
+  /**
+   */
+  public static final class MonitoringServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub<MonitoringServiceBlockingStub> {
+    private MonitoringServiceBlockingStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected MonitoringServiceBlockingStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new MonitoringServiceBlockingStub(channel, callOptions);
+    }
+
+    /**
+     */
+    public monitoring.Monitoring.KpiId createKpi(monitoring.Monitoring.KpiDescriptor request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getCreateKpiMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public monitoring.Monitoring.KpiDescriptor getKpiDescriptor(monitoring.Monitoring.KpiId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getGetKpiDescriptorMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.Empty includeKpi(monitoring.Monitoring.Kpi request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getIncludeKpiMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.Empty monitorKpi(monitoring.Monitoring.MonitorKpiRequest request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getMonitorKpiMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public java.util.Iterator<monitoring.Monitoring.Kpi> getStreamKpi(
+        monitoring.Monitoring.KpiId request) {
+      return io.grpc.stub.ClientCalls.blockingServerStreamingCall(
+          getChannel(), getGetStreamKpiMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public monitoring.Monitoring.Kpi getInstantKpi(monitoring.Monitoring.KpiId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getGetInstantKpiMethod(), getCallOptions(), request);
+    }
+  }
+
+  /**
+   */
+  public static final class MonitoringServiceFutureStub extends io.grpc.stub.AbstractFutureStub<MonitoringServiceFutureStub> {
+    private MonitoringServiceFutureStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected MonitoringServiceFutureStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new MonitoringServiceFutureStub(channel, callOptions);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiId> createKpi(
+        monitoring.Monitoring.KpiDescriptor request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getCreateKpiMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(
+        monitoring.Monitoring.KpiId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getGetKpiDescriptorMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> includeKpi(
+        monitoring.Monitoring.Kpi request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getIncludeKpiMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> monitorKpi(
+        monitoring.Monitoring.MonitorKpiRequest request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getMonitorKpiMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<monitoring.Monitoring.Kpi> getInstantKpi(
+        monitoring.Monitoring.KpiId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getGetInstantKpiMethod(), getCallOptions()), request);
+    }
+  }
+
+  private static final int METHODID_CREATE_KPI = 0;
+  private static final int METHODID_GET_KPI_DESCRIPTOR = 1;
+  private static final int METHODID_INCLUDE_KPI = 2;
+  private static final int METHODID_MONITOR_KPI = 3;
+  private static final int METHODID_GET_STREAM_KPI = 4;
+  private static final int METHODID_GET_INSTANT_KPI = 5;
+
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final MonitoringServiceImplBase serviceImpl;
+    private final int methodId;
+
+    MethodHandlers(MonitoringServiceImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_CREATE_KPI:
+          serviceImpl.createKpi((monitoring.Monitoring.KpiDescriptor) request,
+              (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId>) responseObserver);
+          break;
+        case METHODID_GET_KPI_DESCRIPTOR:
+          serviceImpl.getKpiDescriptor((monitoring.Monitoring.KpiId) request,
+              (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptor>) responseObserver);
+          break;
+        case METHODID_INCLUDE_KPI:
+          serviceImpl.includeKpi((monitoring.Monitoring.Kpi) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
+          break;
+        case METHODID_MONITOR_KPI:
+          serviceImpl.monitorKpi((monitoring.Monitoring.MonitorKpiRequest) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
+          break;
+        case METHODID_GET_STREAM_KPI:
+          serviceImpl.getStreamKpi((monitoring.Monitoring.KpiId) request,
+              (io.grpc.stub.StreamObserver<monitoring.Monitoring.Kpi>) responseObserver);
+          break;
+        case METHODID_GET_INSTANT_KPI:
+          serviceImpl.getInstantKpi((monitoring.Monitoring.KpiId) request,
+              (io.grpc.stub.StreamObserver<monitoring.Monitoring.Kpi>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  private static abstract class MonitoringServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
+    MonitoringServiceBaseDescriptorSupplier() {}
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
+      return monitoring.Monitoring.getDescriptor();
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
+      return getFileDescriptor().findServiceByName("MonitoringService");
+    }
+  }
+
+  private static final class MonitoringServiceFileDescriptorSupplier
+      extends MonitoringServiceBaseDescriptorSupplier {
+    MonitoringServiceFileDescriptorSupplier() {}
+  }
+
+  private static final class MonitoringServiceMethodDescriptorSupplier
+      extends MonitoringServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
+    private final String methodName;
+
+    MonitoringServiceMethodDescriptorSupplier(String methodName) {
+      this.methodName = methodName;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
+      return getServiceDescriptor().findMethodByName(methodName);
+    }
+  }
+
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (MonitoringServiceGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new MonitoringServiceFileDescriptorSupplier())
+              .addMethod(getCreateKpiMethod())
+              .addMethod(getGetKpiDescriptorMethod())
+              .addMethod(getIncludeKpiMethod())
+              .addMethod(getMonitorKpiMethod())
+              .addMethod(getGetStreamKpiMethod())
+              .addMethod(getGetInstantKpiMethod())
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}
diff --git a/src/policy/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java b/src/policy/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java
new file mode 100644
index 000000000..e5157378c
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/monitoring/MutinyMonitoringServiceGrpc.java
@@ -0,0 +1,240 @@
+package monitoring;
+
+import static monitoring.MonitoringServiceGrpc.getServiceDescriptor;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+
+@javax.annotation.Generated(
+value = "by Mutiny Grpc generator",
+comments = "Source: monitoring.proto")
+public final class MutinyMonitoringServiceGrpc implements io.quarkus.grpc.runtime.MutinyGrpc {
+    private MutinyMonitoringServiceGrpc() {}
+
+    public static MutinyMonitoringServiceStub newMutinyStub(io.grpc.Channel channel) {
+        return new MutinyMonitoringServiceStub(channel);
+    }
+
+    
+    public static final class MutinyMonitoringServiceStub extends io.grpc.stub.AbstractStub<MutinyMonitoringServiceStub> implements io.quarkus.grpc.runtime.MutinyStub {
+        private MonitoringServiceGrpc.MonitoringServiceStub delegateStub;
+
+        private MutinyMonitoringServiceStub(io.grpc.Channel channel) {
+            super(channel);
+            delegateStub = MonitoringServiceGrpc.newStub(channel);
+        }
+
+        private MutinyMonitoringServiceStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+            super(channel, callOptions);
+            delegateStub = MonitoringServiceGrpc.newStub(channel).build(channel, callOptions);
+        }
+
+        @Override
+        protected MutinyMonitoringServiceStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+            return new MutinyMonitoringServiceStub(channel, callOptions);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::createKpi);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getKpiDescriptor);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::includeKpi);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> monitorKpi(monitoring.Monitoring.MonitorKpiRequest request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::monitorKpi);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.Kpi> getInstantKpi(monitoring.Monitoring.KpiId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getInstantKpi);
+        }
+
+        
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToMany(request, delegateStub::getStreamKpi);
+        }
+
+    }
+
+    
+    public static abstract class MonitoringServiceImplBase implements io.grpc.BindableService {
+
+        private String compression;
+        /**
+        * Set whether the server will try to use a compressed response.
+        *
+        * @param compression the compression, e.g {@code gzip}
+        */
+        public MonitoringServiceImplBase withCompression(String compression) {
+        this.compression = compression;
+        return this;
+        }
+
+
+        
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiId> createKpi(monitoring.Monitoring.KpiDescriptor request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.KpiDescriptor> getKpiDescriptor(monitoring.Monitoring.KpiId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> includeKpi(monitoring.Monitoring.Kpi request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> monitorKpi(monitoring.Monitoring.MonitorKpiRequest request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<monitoring.Monitoring.Kpi> getInstantKpi(monitoring.Monitoring.KpiId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Multi<monitoring.Monitoring.Kpi> getStreamKpi(monitoring.Monitoring.KpiId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+            return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+                    .addMethod(
+                            monitoring.MonitoringServiceGrpc.getCreateKpiMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            monitoring.Monitoring.KpiDescriptor,
+                                            monitoring.Monitoring.KpiId>(
+                                            this, METHODID_CREATE_KPI, compression)))
+                    .addMethod(
+                            monitoring.MonitoringServiceGrpc.getGetKpiDescriptorMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            monitoring.Monitoring.KpiId,
+                                            monitoring.Monitoring.KpiDescriptor>(
+                                            this, METHODID_GET_KPI_DESCRIPTOR, compression)))
+                    .addMethod(
+                            monitoring.MonitoringServiceGrpc.getIncludeKpiMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            monitoring.Monitoring.Kpi,
+                                            context.ContextOuterClass.Empty>(
+                                            this, METHODID_INCLUDE_KPI, compression)))
+                    .addMethod(
+                            monitoring.MonitoringServiceGrpc.getMonitorKpiMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            monitoring.Monitoring.MonitorKpiRequest,
+                                            context.ContextOuterClass.Empty>(
+                                            this, METHODID_MONITOR_KPI, compression)))
+                    .addMethod(
+                            monitoring.MonitoringServiceGrpc.getGetStreamKpiMethod(),
+                            asyncServerStreamingCall(
+                                    new MethodHandlers<
+                                            monitoring.Monitoring.KpiId,
+                                            monitoring.Monitoring.Kpi>(
+                                            this, METHODID_GET_STREAM_KPI, compression)))
+                    .addMethod(
+                            monitoring.MonitoringServiceGrpc.getGetInstantKpiMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            monitoring.Monitoring.KpiId,
+                                            monitoring.Monitoring.Kpi>(
+                                            this, METHODID_GET_INSTANT_KPI, compression)))
+                    .build();
+        }
+    }
+
+    private static final int METHODID_CREATE_KPI = 0;
+    private static final int METHODID_GET_KPI_DESCRIPTOR = 1;
+    private static final int METHODID_INCLUDE_KPI = 2;
+    private static final int METHODID_MONITOR_KPI = 3;
+    private static final int METHODID_GET_STREAM_KPI = 4;
+    private static final int METHODID_GET_INSTANT_KPI = 5;
+
+    private static final class MethodHandlers<Req, Resp> implements
+            io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+            io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+            io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+            io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+        private final MonitoringServiceImplBase serviceImpl;
+        private final int methodId;
+        private final String compression;
+
+        MethodHandlers(MonitoringServiceImplBase serviceImpl, int methodId, String compression) {
+            this.serviceImpl = serviceImpl;
+            this.methodId = methodId;
+            this.compression = compression;
+        }
+
+        @java.lang.Override
+        @java.lang.SuppressWarnings("unchecked")
+        public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+            switch (methodId) {
+                case METHODID_CREATE_KPI:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.KpiDescriptor) request,
+                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiId>) responseObserver,
+                            compression,
+                            serviceImpl::createKpi);
+                    break;
+                case METHODID_GET_KPI_DESCRIPTOR:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.KpiId) request,
+                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.KpiDescriptor>) responseObserver,
+                            compression,
+                            serviceImpl::getKpiDescriptor);
+                    break;
+                case METHODID_INCLUDE_KPI:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.Kpi) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
+                            compression,
+                            serviceImpl::includeKpi);
+                    break;
+                case METHODID_MONITOR_KPI:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.MonitorKpiRequest) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
+                            compression,
+                            serviceImpl::monitorKpi);
+                    break;
+                case METHODID_GET_STREAM_KPI:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToMany((monitoring.Monitoring.KpiId) request,
+                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.Kpi>) responseObserver,
+                            compression,
+                            serviceImpl::getStreamKpi);
+                    break;
+                case METHODID_GET_INSTANT_KPI:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((monitoring.Monitoring.KpiId) request,
+                            (io.grpc.stub.StreamObserver<monitoring.Monitoring.Kpi>) responseObserver,
+                            compression,
+                            serviceImpl::getInstantKpi);
+                    break;
+                default:
+                    throw new java.lang.AssertionError();
+            }
+        }
+
+        @java.lang.Override
+        @java.lang.SuppressWarnings("unchecked")
+        public io.grpc.stub.StreamObserver<Req> invoke(io.grpc.stub.StreamObserver<Resp> responseObserver) {
+            switch (methodId) {
+                default:
+                    throw new java.lang.AssertionError();
+            }
+        }
+    }
+
+}
\ No newline at end of file
-- 
GitLab


From 6288249a2712025a4274c59714ba46e74d8310fd Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Wed, 15 Jun 2022 13:16:18 +0300
Subject: [PATCH 48/60] feat(policy): introduce policy-condition.proto file

---
 proto/policy-condition.proto                  |   41 +
 .../src/main/proto/policy-condition.proto     |    1 +
 .../grpc/policy/PolicyCondition.java          | 1322 +++++++++++++++++
 3 files changed, 1364 insertions(+)
 create mode 100644 proto/policy-condition.proto
 create mode 120000 src/policy/src/main/proto/policy-condition.proto
 create mode 100644 src/policy/target/generated-sources/grpc/policy/PolicyCondition.java

diff --git a/proto/policy-condition.proto b/proto/policy-condition.proto
new file mode 100644
index 000000000..747eead85
--- /dev/null
+++ b/proto/policy-condition.proto
@@ -0,0 +1,41 @@
+// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package policy;
+
+import "monitoring.proto";
+
+// Condition
+message PolicyRuleCondition {
+  monitoring.KpiId kpiId = 1;
+  PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;
+  monitoring.KpiValue kpiValue = 3;
+}
+
+// Operator to be used when comparing Kpis with condition values
+enum PolicyRuleConditionComparisonOperator {
+  EQUAL = 0;              // Kpi is equal with value
+  NOT_EQUAL = 1;          // Kpi is not equal with value
+  LESS_THAN = 2;          // Kpi is less than value
+  LESS_THAN_EQUAL = 3;    // Kpi is less than or equal with value
+  GREATER_THAN = 4;       // Kpi is greater than value
+  GREATER_THAN_EQUAL = 5; // Kpi is less than or equal with value
+}
+
+// Operator to be used when evaluating each condition
+enum PolicyRuleConditionEvaluationOperator {
+  AND = 0;  // Logical AND operator
+  OR = 1;   // Logical OR operator
+}
\ No newline at end of file
diff --git a/src/policy/src/main/proto/policy-condition.proto b/src/policy/src/main/proto/policy-condition.proto
new file mode 120000
index 000000000..f847d8b60
--- /dev/null
+++ b/src/policy/src/main/proto/policy-condition.proto
@@ -0,0 +1 @@
+../../../../../proto/policy-condition.proto
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/policy/PolicyCondition.java b/src/policy/target/generated-sources/grpc/policy/PolicyCondition.java
new file mode 100644
index 000000000..509c3db6a
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/policy/PolicyCondition.java
@@ -0,0 +1,1322 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: policy-condition.proto
+
+package policy;
+
+public final class PolicyCondition {
+  private PolicyCondition() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  /**
+   * <pre>
+   * Operator to be used when comparing Kpis with condition values
+   * </pre>
+   *
+   * Protobuf enum {@code policy.PolicyRuleConditionComparisonOperator}
+   */
+  public enum PolicyRuleConditionComparisonOperator
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <pre>
+     * Kpi is equal with value
+     * </pre>
+     *
+     * <code>EQUAL = 0;</code>
+     */
+    EQUAL(0),
+    /**
+     * <pre>
+     * Kpi is not equal with value
+     * </pre>
+     *
+     * <code>NOT_EQUAL = 1;</code>
+     */
+    NOT_EQUAL(1),
+    /**
+     * <pre>
+     * Kpi is less than value
+     * </pre>
+     *
+     * <code>LESS_THAN = 2;</code>
+     */
+    LESS_THAN(2),
+    /**
+     * <pre>
+     * Kpi is less than or equal with value
+     * </pre>
+     *
+     * <code>LESS_THAN_EQUAL = 3;</code>
+     */
+    LESS_THAN_EQUAL(3),
+    /**
+     * <pre>
+     * Kpi is greater than value
+     * </pre>
+     *
+     * <code>GREATER_THAN = 4;</code>
+     */
+    GREATER_THAN(4),
+    /**
+     * <pre>
+     * Kpi is less than or equal with value
+     * </pre>
+     *
+     * <code>GREATER_THAN_EQUAL = 5;</code>
+     */
+    GREATER_THAN_EQUAL(5),
+    UNRECOGNIZED(-1),
+    ;
+
+    /**
+     * <pre>
+     * Kpi is equal with value
+     * </pre>
+     *
+     * <code>EQUAL = 0;</code>
+     */
+    public static final int EQUAL_VALUE = 0;
+    /**
+     * <pre>
+     * Kpi is not equal with value
+     * </pre>
+     *
+     * <code>NOT_EQUAL = 1;</code>
+     */
+    public static final int NOT_EQUAL_VALUE = 1;
+    /**
+     * <pre>
+     * Kpi is less than value
+     * </pre>
+     *
+     * <code>LESS_THAN = 2;</code>
+     */
+    public static final int LESS_THAN_VALUE = 2;
+    /**
+     * <pre>
+     * Kpi is less than or equal with value
+     * </pre>
+     *
+     * <code>LESS_THAN_EQUAL = 3;</code>
+     */
+    public static final int LESS_THAN_EQUAL_VALUE = 3;
+    /**
+     * <pre>
+     * Kpi is greater than value
+     * </pre>
+     *
+     * <code>GREATER_THAN = 4;</code>
+     */
+    public static final int GREATER_THAN_VALUE = 4;
+    /**
+     * <pre>
+     * Kpi is less than or equal with value
+     * </pre>
+     *
+     * <code>GREATER_THAN_EQUAL = 5;</code>
+     */
+    public static final int GREATER_THAN_EQUAL_VALUE = 5;
+
+
+    public final int getNumber() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     * @deprecated Use {@link #forNumber(int)} instead.
+     */
+    @java.lang.Deprecated
+    public static PolicyRuleConditionComparisonOperator valueOf(int value) {
+      return forNumber(value);
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     */
+    public static PolicyRuleConditionComparisonOperator forNumber(int value) {
+      switch (value) {
+        case 0: return EQUAL;
+        case 1: return NOT_EQUAL;
+        case 2: return LESS_THAN;
+        case 3: return LESS_THAN_EQUAL;
+        case 4: return GREATER_THAN;
+        case 5: return GREATER_THAN_EQUAL;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<PolicyRuleConditionComparisonOperator>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        PolicyRuleConditionComparisonOperator> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<PolicyRuleConditionComparisonOperator>() {
+            public PolicyRuleConditionComparisonOperator findValueByNumber(int number) {
+              return PolicyRuleConditionComparisonOperator.forNumber(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalStateException(
+            "Can't get the descriptor of an unrecognized enum value.");
+      }
+      return getDescriptor().getValues().get(ordinal());
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return policy.PolicyCondition.getDescriptor().getEnumTypes().get(0);
+    }
+
+    private static final PolicyRuleConditionComparisonOperator[] VALUES = values();
+
+    public static PolicyRuleConditionComparisonOperator valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int value;
+
+    private PolicyRuleConditionComparisonOperator(int value) {
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:policy.PolicyRuleConditionComparisonOperator)
+  }
+
+  /**
+   * <pre>
+   * Operator to be used when evaluating each condition
+   * </pre>
+   *
+   * Protobuf enum {@code policy.PolicyRuleConditionEvaluationOperator}
+   */
+  public enum PolicyRuleConditionEvaluationOperator
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <pre>
+     * Logical AND operator
+     * </pre>
+     *
+     * <code>AND = 0;</code>
+     */
+    AND(0),
+    /**
+     * <pre>
+     * Logical OR operator
+     * </pre>
+     *
+     * <code>OR = 1;</code>
+     */
+    OR(1),
+    UNRECOGNIZED(-1),
+    ;
+
+    /**
+     * <pre>
+     * Logical AND operator
+     * </pre>
+     *
+     * <code>AND = 0;</code>
+     */
+    public static final int AND_VALUE = 0;
+    /**
+     * <pre>
+     * Logical OR operator
+     * </pre>
+     *
+     * <code>OR = 1;</code>
+     */
+    public static final int OR_VALUE = 1;
+
+
+    public final int getNumber() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     * @deprecated Use {@link #forNumber(int)} instead.
+     */
+    @java.lang.Deprecated
+    public static PolicyRuleConditionEvaluationOperator valueOf(int value) {
+      return forNumber(value);
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     */
+    public static PolicyRuleConditionEvaluationOperator forNumber(int value) {
+      switch (value) {
+        case 0: return AND;
+        case 1: return OR;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<PolicyRuleConditionEvaluationOperator>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        PolicyRuleConditionEvaluationOperator> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<PolicyRuleConditionEvaluationOperator>() {
+            public PolicyRuleConditionEvaluationOperator findValueByNumber(int number) {
+              return PolicyRuleConditionEvaluationOperator.forNumber(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalStateException(
+            "Can't get the descriptor of an unrecognized enum value.");
+      }
+      return getDescriptor().getValues().get(ordinal());
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return policy.PolicyCondition.getDescriptor().getEnumTypes().get(1);
+    }
+
+    private static final PolicyRuleConditionEvaluationOperator[] VALUES = values();
+
+    public static PolicyRuleConditionEvaluationOperator valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int value;
+
+    private PolicyRuleConditionEvaluationOperator(int value) {
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:policy.PolicyRuleConditionEvaluationOperator)
+  }
+
+  public interface PolicyRuleConditionOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleCondition)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.monitoring.KpiId kpiId = 1;</code>
+     * @return Whether the kpiId field is set.
+     */
+    boolean hasKpiId();
+    /**
+     * <code>.monitoring.KpiId kpiId = 1;</code>
+     * @return The kpiId.
+     */
+    monitoring.Monitoring.KpiId getKpiId();
+    /**
+     * <code>.monitoring.KpiId kpiId = 1;</code>
+     */
+    monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
+
+    /**
+     * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+     * @return The enum numeric value on the wire for polRuleConditionComparisonOperator.
+     */
+    int getPolRuleConditionComparisonOperatorValue();
+    /**
+     * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+     * @return The polRuleConditionComparisonOperator.
+     */
+    policy.PolicyCondition.PolicyRuleConditionComparisonOperator getPolRuleConditionComparisonOperator();
+
+    /**
+     * <code>.monitoring.KpiValue kpiValue = 3;</code>
+     * @return Whether the kpiValue field is set.
+     */
+    boolean hasKpiValue();
+    /**
+     * <code>.monitoring.KpiValue kpiValue = 3;</code>
+     * @return The kpiValue.
+     */
+    monitoring.Monitoring.KpiValue getKpiValue();
+    /**
+     * <code>.monitoring.KpiValue kpiValue = 3;</code>
+     */
+    monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder();
+  }
+  /**
+   * <pre>
+   * Condition
+   * </pre>
+   *
+   * Protobuf type {@code policy.PolicyRuleCondition}
+   */
+  public static final class PolicyRuleCondition extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:policy.PolicyRuleCondition)
+      PolicyRuleConditionOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use PolicyRuleCondition.newBuilder() to construct.
+    private PolicyRuleCondition(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private PolicyRuleCondition() {
+      polRuleConditionComparisonOperator_ = 0;
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new PolicyRuleCondition();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PolicyRuleCondition(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              monitoring.Monitoring.KpiId.Builder subBuilder = null;
+              if (kpiId_ != null) {
+                subBuilder = kpiId_.toBuilder();
+              }
+              kpiId_ = input.readMessage(monitoring.Monitoring.KpiId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(kpiId_);
+                kpiId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 16: {
+              int rawValue = input.readEnum();
+
+              polRuleConditionComparisonOperator_ = rawValue;
+              break;
+            }
+            case 26: {
+              monitoring.Monitoring.KpiValue.Builder subBuilder = null;
+              if (kpiValue_ != null) {
+                subBuilder = kpiValue_.toBuilder();
+              }
+              kpiValue_ = input.readMessage(monitoring.Monitoring.KpiValue.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(kpiValue_);
+                kpiValue_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return policy.PolicyCondition.internal_static_policy_PolicyRuleCondition_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return policy.PolicyCondition.internal_static_policy_PolicyRuleCondition_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              policy.PolicyCondition.PolicyRuleCondition.class, policy.PolicyCondition.PolicyRuleCondition.Builder.class);
+    }
+
+    public static final int KPIID_FIELD_NUMBER = 1;
+    private monitoring.Monitoring.KpiId kpiId_;
+    /**
+     * <code>.monitoring.KpiId kpiId = 1;</code>
+     * @return Whether the kpiId field is set.
+     */
+    @java.lang.Override
+    public boolean hasKpiId() {
+      return kpiId_ != null;
+    }
+    /**
+     * <code>.monitoring.KpiId kpiId = 1;</code>
+     * @return The kpiId.
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiId getKpiId() {
+      return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+    }
+    /**
+     * <code>.monitoring.KpiId kpiId = 1;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+      return getKpiId();
+    }
+
+    public static final int POLRULECONDITIONCOMPARISONOPERATOR_FIELD_NUMBER = 2;
+    private int polRuleConditionComparisonOperator_;
+    /**
+     * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+     * @return The enum numeric value on the wire for polRuleConditionComparisonOperator.
+     */
+    @java.lang.Override public int getPolRuleConditionComparisonOperatorValue() {
+      return polRuleConditionComparisonOperator_;
+    }
+    /**
+     * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+     * @return The polRuleConditionComparisonOperator.
+     */
+    @java.lang.Override public policy.PolicyCondition.PolicyRuleConditionComparisonOperator getPolRuleConditionComparisonOperator() {
+      @SuppressWarnings("deprecation")
+      policy.PolicyCondition.PolicyRuleConditionComparisonOperator result = policy.PolicyCondition.PolicyRuleConditionComparisonOperator.valueOf(polRuleConditionComparisonOperator_);
+      return result == null ? policy.PolicyCondition.PolicyRuleConditionComparisonOperator.UNRECOGNIZED : result;
+    }
+
+    public static final int KPIVALUE_FIELD_NUMBER = 3;
+    private monitoring.Monitoring.KpiValue kpiValue_;
+    /**
+     * <code>.monitoring.KpiValue kpiValue = 3;</code>
+     * @return Whether the kpiValue field is set.
+     */
+    @java.lang.Override
+    public boolean hasKpiValue() {
+      return kpiValue_ != null;
+    }
+    /**
+     * <code>.monitoring.KpiValue kpiValue = 3;</code>
+     * @return The kpiValue.
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValue getKpiValue() {
+      return kpiValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+    }
+    /**
+     * <code>.monitoring.KpiValue kpiValue = 3;</code>
+     */
+    @java.lang.Override
+    public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
+      return getKpiValue();
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (kpiId_ != null) {
+        output.writeMessage(1, getKpiId());
+      }
+      if (polRuleConditionComparisonOperator_ != policy.PolicyCondition.PolicyRuleConditionComparisonOperator.EQUAL.getNumber()) {
+        output.writeEnum(2, polRuleConditionComparisonOperator_);
+      }
+      if (kpiValue_ != null) {
+        output.writeMessage(3, getKpiValue());
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (kpiId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getKpiId());
+      }
+      if (polRuleConditionComparisonOperator_ != policy.PolicyCondition.PolicyRuleConditionComparisonOperator.EQUAL.getNumber()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(2, polRuleConditionComparisonOperator_);
+      }
+      if (kpiValue_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, getKpiValue());
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof policy.PolicyCondition.PolicyRuleCondition)) {
+        return super.equals(obj);
+      }
+      policy.PolicyCondition.PolicyRuleCondition other = (policy.PolicyCondition.PolicyRuleCondition) obj;
+
+      if (hasKpiId() != other.hasKpiId()) return false;
+      if (hasKpiId()) {
+        if (!getKpiId()
+            .equals(other.getKpiId())) return false;
+      }
+      if (polRuleConditionComparisonOperator_ != other.polRuleConditionComparisonOperator_) return false;
+      if (hasKpiValue() != other.hasKpiValue()) return false;
+      if (hasKpiValue()) {
+        if (!getKpiValue()
+            .equals(other.getKpiValue())) return false;
+      }
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasKpiId()) {
+        hash = (37 * hash) + KPIID_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiId().hashCode();
+      }
+      hash = (37 * hash) + POLRULECONDITIONCOMPARISONOPERATOR_FIELD_NUMBER;
+      hash = (53 * hash) + polRuleConditionComparisonOperator_;
+      if (hasKpiValue()) {
+        hash = (37 * hash) + KPIVALUE_FIELD_NUMBER;
+        hash = (53 * hash) + getKpiValue().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.PolicyCondition.PolicyRuleCondition parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(policy.PolicyCondition.PolicyRuleCondition prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * Condition
+     * </pre>
+     *
+     * Protobuf type {@code policy.PolicyRuleCondition}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleCondition)
+        policy.PolicyCondition.PolicyRuleConditionOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return policy.PolicyCondition.internal_static_policy_PolicyRuleCondition_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return policy.PolicyCondition.internal_static_policy_PolicyRuleCondition_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                policy.PolicyCondition.PolicyRuleCondition.class, policy.PolicyCondition.PolicyRuleCondition.Builder.class);
+      }
+
+      // Construct using policy.PolicyCondition.PolicyRuleCondition.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+        polRuleConditionComparisonOperator_ = 0;
+
+        if (kpiValueBuilder_ == null) {
+          kpiValue_ = null;
+        } else {
+          kpiValue_ = null;
+          kpiValueBuilder_ = null;
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return policy.PolicyCondition.internal_static_policy_PolicyRuleCondition_descriptor;
+      }
+
+      @java.lang.Override
+      public policy.PolicyCondition.PolicyRuleCondition getDefaultInstanceForType() {
+        return policy.PolicyCondition.PolicyRuleCondition.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public policy.PolicyCondition.PolicyRuleCondition build() {
+        policy.PolicyCondition.PolicyRuleCondition result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public policy.PolicyCondition.PolicyRuleCondition buildPartial() {
+        policy.PolicyCondition.PolicyRuleCondition result = new policy.PolicyCondition.PolicyRuleCondition(this);
+        if (kpiIdBuilder_ == null) {
+          result.kpiId_ = kpiId_;
+        } else {
+          result.kpiId_ = kpiIdBuilder_.build();
+        }
+        result.polRuleConditionComparisonOperator_ = polRuleConditionComparisonOperator_;
+        if (kpiValueBuilder_ == null) {
+          result.kpiValue_ = kpiValue_;
+        } else {
+          result.kpiValue_ = kpiValueBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof policy.PolicyCondition.PolicyRuleCondition) {
+          return mergeFrom((policy.PolicyCondition.PolicyRuleCondition)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(policy.PolicyCondition.PolicyRuleCondition other) {
+        if (other == policy.PolicyCondition.PolicyRuleCondition.getDefaultInstance()) return this;
+        if (other.hasKpiId()) {
+          mergeKpiId(other.getKpiId());
+        }
+        if (other.polRuleConditionComparisonOperator_ != 0) {
+          setPolRuleConditionComparisonOperatorValue(other.getPolRuleConditionComparisonOperatorValue());
+        }
+        if (other.hasKpiValue()) {
+          mergeKpiValue(other.getKpiValue());
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        policy.PolicyCondition.PolicyRuleCondition parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (policy.PolicyCondition.PolicyRuleCondition) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+
+      private monitoring.Monitoring.KpiId kpiId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> kpiIdBuilder_;
+      /**
+       * <code>.monitoring.KpiId kpiId = 1;</code>
+       * @return Whether the kpiId field is set.
+       */
+      public boolean hasKpiId() {
+        return kpiIdBuilder_ != null || kpiId_ != null;
+      }
+      /**
+       * <code>.monitoring.KpiId kpiId = 1;</code>
+       * @return The kpiId.
+       */
+      public monitoring.Monitoring.KpiId getKpiId() {
+        if (kpiIdBuilder_ == null) {
+          return kpiId_ == null ? monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+        } else {
+          return kpiIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.KpiId kpiId = 1;</code>
+       */
+      public Builder setKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          kpiId_ = value;
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpiId = 1;</code>
+       */
+      public Builder setKpiId(
+          monitoring.Monitoring.KpiId.Builder builderForValue) {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiIdBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpiId = 1;</code>
+       */
+      public Builder mergeKpiId(monitoring.Monitoring.KpiId value) {
+        if (kpiIdBuilder_ == null) {
+          if (kpiId_ != null) {
+            kpiId_ =
+              monitoring.Monitoring.KpiId.newBuilder(kpiId_).mergeFrom(value).buildPartial();
+          } else {
+            kpiId_ = value;
+          }
+          onChanged();
+        } else {
+          kpiIdBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpiId = 1;</code>
+       */
+      public Builder clearKpiId() {
+        if (kpiIdBuilder_ == null) {
+          kpiId_ = null;
+          onChanged();
+        } else {
+          kpiId_ = null;
+          kpiIdBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiId kpiId = 1;</code>
+       */
+      public monitoring.Monitoring.KpiId.Builder getKpiIdBuilder() {
+        
+        onChanged();
+        return getKpiIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.KpiId kpiId = 1;</code>
+       */
+      public monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder() {
+        if (kpiIdBuilder_ != null) {
+          return kpiIdBuilder_.getMessageOrBuilder();
+        } else {
+          return kpiId_ == null ?
+              monitoring.Monitoring.KpiId.getDefaultInstance() : kpiId_;
+        }
+      }
+      /**
+       * <code>.monitoring.KpiId kpiId = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder> 
+          getKpiIdFieldBuilder() {
+        if (kpiIdBuilder_ == null) {
+          kpiIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.KpiId, monitoring.Monitoring.KpiId.Builder, monitoring.Monitoring.KpiIdOrBuilder>(
+                  getKpiId(),
+                  getParentForChildren(),
+                  isClean());
+          kpiId_ = null;
+        }
+        return kpiIdBuilder_;
+      }
+
+      private int polRuleConditionComparisonOperator_ = 0;
+      /**
+       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+       * @return The enum numeric value on the wire for polRuleConditionComparisonOperator.
+       */
+      @java.lang.Override public int getPolRuleConditionComparisonOperatorValue() {
+        return polRuleConditionComparisonOperator_;
+      }
+      /**
+       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+       * @param value The enum numeric value on the wire for polRuleConditionComparisonOperator to set.
+       * @return This builder for chaining.
+       */
+      public Builder setPolRuleConditionComparisonOperatorValue(int value) {
+        
+        polRuleConditionComparisonOperator_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+       * @return The polRuleConditionComparisonOperator.
+       */
+      @java.lang.Override
+      public policy.PolicyCondition.PolicyRuleConditionComparisonOperator getPolRuleConditionComparisonOperator() {
+        @SuppressWarnings("deprecation")
+        policy.PolicyCondition.PolicyRuleConditionComparisonOperator result = policy.PolicyCondition.PolicyRuleConditionComparisonOperator.valueOf(polRuleConditionComparisonOperator_);
+        return result == null ? policy.PolicyCondition.PolicyRuleConditionComparisonOperator.UNRECOGNIZED : result;
+      }
+      /**
+       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+       * @param value The polRuleConditionComparisonOperator to set.
+       * @return This builder for chaining.
+       */
+      public Builder setPolRuleConditionComparisonOperator(policy.PolicyCondition.PolicyRuleConditionComparisonOperator value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        
+        polRuleConditionComparisonOperator_ = value.getNumber();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearPolRuleConditionComparisonOperator() {
+        
+        polRuleConditionComparisonOperator_ = 0;
+        onChanged();
+        return this;
+      }
+
+      private monitoring.Monitoring.KpiValue kpiValue_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> kpiValueBuilder_;
+      /**
+       * <code>.monitoring.KpiValue kpiValue = 3;</code>
+       * @return Whether the kpiValue field is set.
+       */
+      public boolean hasKpiValue() {
+        return kpiValueBuilder_ != null || kpiValue_ != null;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpiValue = 3;</code>
+       * @return The kpiValue.
+       */
+      public monitoring.Monitoring.KpiValue getKpiValue() {
+        if (kpiValueBuilder_ == null) {
+          return kpiValue_ == null ? monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+        } else {
+          return kpiValueBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>.monitoring.KpiValue kpiValue = 3;</code>
+       */
+      public Builder setKpiValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiValueBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          kpiValue_ = value;
+          onChanged();
+        } else {
+          kpiValueBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpiValue = 3;</code>
+       */
+      public Builder setKpiValue(
+          monitoring.Monitoring.KpiValue.Builder builderForValue) {
+        if (kpiValueBuilder_ == null) {
+          kpiValue_ = builderForValue.build();
+          onChanged();
+        } else {
+          kpiValueBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpiValue = 3;</code>
+       */
+      public Builder mergeKpiValue(monitoring.Monitoring.KpiValue value) {
+        if (kpiValueBuilder_ == null) {
+          if (kpiValue_ != null) {
+            kpiValue_ =
+              monitoring.Monitoring.KpiValue.newBuilder(kpiValue_).mergeFrom(value).buildPartial();
+          } else {
+            kpiValue_ = value;
+          }
+          onChanged();
+        } else {
+          kpiValueBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpiValue = 3;</code>
+       */
+      public Builder clearKpiValue() {
+        if (kpiValueBuilder_ == null) {
+          kpiValue_ = null;
+          onChanged();
+        } else {
+          kpiValue_ = null;
+          kpiValueBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <code>.monitoring.KpiValue kpiValue = 3;</code>
+       */
+      public monitoring.Monitoring.KpiValue.Builder getKpiValueBuilder() {
+        
+        onChanged();
+        return getKpiValueFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>.monitoring.KpiValue kpiValue = 3;</code>
+       */
+      public monitoring.Monitoring.KpiValueOrBuilder getKpiValueOrBuilder() {
+        if (kpiValueBuilder_ != null) {
+          return kpiValueBuilder_.getMessageOrBuilder();
+        } else {
+          return kpiValue_ == null ?
+              monitoring.Monitoring.KpiValue.getDefaultInstance() : kpiValue_;
+        }
+      }
+      /**
+       * <code>.monitoring.KpiValue kpiValue = 3;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder> 
+          getKpiValueFieldBuilder() {
+        if (kpiValueBuilder_ == null) {
+          kpiValueBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              monitoring.Monitoring.KpiValue, monitoring.Monitoring.KpiValue.Builder, monitoring.Monitoring.KpiValueOrBuilder>(
+                  getKpiValue(),
+                  getParentForChildren(),
+                  isClean());
+          kpiValue_ = null;
+        }
+        return kpiValueBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleCondition)
+    }
+
+    // @@protoc_insertion_point(class_scope:policy.PolicyRuleCondition)
+    private static final policy.PolicyCondition.PolicyRuleCondition DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new policy.PolicyCondition.PolicyRuleCondition();
+    }
+
+    public static policy.PolicyCondition.PolicyRuleCondition getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<PolicyRuleCondition>
+        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleCondition>() {
+      @java.lang.Override
+      public PolicyRuleCondition parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PolicyRuleCondition(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<PolicyRuleCondition> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PolicyRuleCondition> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public policy.PolicyCondition.PolicyRuleCondition getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_policy_PolicyRuleCondition_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_policy_PolicyRuleCondition_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\026policy-condition.proto\022\006policy\032\020monito" +
+      "ring.proto\"\272\001\n\023PolicyRuleCondition\022 \n\005kp" +
+      "iId\030\001 \001(\0132\021.monitoring.KpiId\022Y\n\"polRuleC" +
+      "onditionComparisonOperator\030\002 \001(\0162-.polic" +
+      "y.PolicyRuleConditionComparisonOperator\022" +
+      "&\n\010kpiValue\030\003 \001(\0132\024.monitoring.KpiValue*" +
+      "\217\001\n%PolicyRuleConditionComparisonOperato" +
+      "r\022\t\n\005EQUAL\020\000\022\r\n\tNOT_EQUAL\020\001\022\r\n\tLESS_THAN" +
+      "\020\002\022\023\n\017LESS_THAN_EQUAL\020\003\022\020\n\014GREATER_THAN\020" +
+      "\004\022\026\n\022GREATER_THAN_EQUAL\020\005*8\n%PolicyRuleC" +
+      "onditionEvaluationOperator\022\007\n\003AND\020\000\022\006\n\002O" +
+      "R\020\001b\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          monitoring.Monitoring.getDescriptor(),
+        });
+    internal_static_policy_PolicyRuleCondition_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_policy_PolicyRuleCondition_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_policy_PolicyRuleCondition_descriptor,
+        new java.lang.String[] { "KpiId", "PolRuleConditionComparisonOperator", "KpiValue", });
+    monitoring.Monitoring.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
-- 
GitLab


From daee23aef2b8bc80ebf3f2a635dae5a7ba631f01 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Wed, 15 Jun 2022 13:18:55 +0300
Subject: [PATCH 49/60] feat(policy): update policy.proto

---
 proto/policy-action.proto                     |   29 +
 proto/policy-condition.proto                  |   24 +-
 proto/policy.proto                            |   39 +-
 src/policy/src/main/proto/policy-action.proto |    1 +
 .../generated-sources/grpc/policy/Policy.java | 4729 ++++-------------
 .../grpc/policy/PolicyAction.java             |  932 ++++
 .../grpc/policy/PolicyCondition.java          |  306 +-
 7 files changed, 2061 insertions(+), 3999 deletions(-)
 create mode 100644 proto/policy-action.proto
 create mode 120000 src/policy/src/main/proto/policy-action.proto
 create mode 100644 src/policy/target/generated-sources/grpc/policy/PolicyAction.java

diff --git a/proto/policy-action.proto b/proto/policy-action.proto
new file mode 100644
index 000000000..374b59751
--- /dev/null
+++ b/proto/policy-action.proto
@@ -0,0 +1,29 @@
+// Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+syntax = "proto3";
+package policy;
+
+// Action
+message PolicyRuleAction {
+  PolicyRuleActionEnum action = 1;
+  repeated string parameters = 2;
+}
+
+enum PolicyRuleActionEnum {
+  POLICYRULE_ACTION_NO_ACTION = 0;
+  POLICYRULE_ACTION_SET_DEVICE_STATUS = 1;
+  POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE = 2;
+  POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT = 3;
+}
diff --git a/proto/policy-condition.proto b/proto/policy-condition.proto
index 747eead85..7cd657667 100644
--- a/proto/policy-condition.proto
+++ b/proto/policy-condition.proto
@@ -20,22 +20,24 @@ import "monitoring.proto";
 // Condition
 message PolicyRuleCondition {
   monitoring.KpiId kpiId = 1;
-  PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;
+  NumericalOperator numericalOperator = 2;
   monitoring.KpiValue kpiValue = 3;
 }
 
 // Operator to be used when comparing Kpis with condition values
-enum PolicyRuleConditionComparisonOperator {
-  EQUAL = 0;              // Kpi is equal with value
-  NOT_EQUAL = 1;          // Kpi is not equal with value
-  LESS_THAN = 2;          // Kpi is less than value
-  LESS_THAN_EQUAL = 3;    // Kpi is less than or equal with value
-  GREATER_THAN = 4;       // Kpi is greater than value
-  GREATER_THAN_EQUAL = 5; // Kpi is less than or equal with value
+enum NumericalOperator {
+  POLICYRULE_CONDITION_NUMERICAL_UNDEFINED = 0;          // Kpi numerical operator undefined
+  POLICYRULE_CONDITION_NUMERICAL_EQUAL = 1;              // Kpi is equal with value
+  POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL = 2;          // Kpi is not equal with value
+  POLICYRULE_CONDITION_NUMERICAL_LESS_THAN = 3;          // Kpi is less than value
+  POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL = 4;    // Kpi is less than or equal with value
+  POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN = 5;       // Kpi is greater than value
+  POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL = 6; // Kpi is less than or equal with value
 }
 
 // Operator to be used when evaluating each condition
-enum PolicyRuleConditionEvaluationOperator {
-  AND = 0;  // Logical AND operator
-  OR = 1;   // Logical OR operator
+enum BooleanOperator {
+  POLICYRULE_CONDITION_BOOLEAN_UNDEFINED = 0;  // Boolean operator undefined
+  POLICYRULE_CONDITION_BOOLEAN_AND = 1;        // Boolean AND operator
+  POLICYRULE_CONDITION_BOOLEAN_OR = 2;         // Boolean OR operator
 }
\ No newline at end of file
diff --git a/proto/policy.proto b/proto/policy.proto
index 447eda2e1..0887ae955 100644
--- a/proto/policy.proto
+++ b/proto/policy.proto
@@ -16,6 +16,8 @@ syntax = "proto3";
 package policy;
 
 import "context.proto";
+import "policy-condition.proto";
+import "policy-action.proto";
 
 service PolicyService {
   rpc PolicyAdd (PolicyRule) returns (PolicyRuleState) {}
@@ -46,14 +48,6 @@ message PolicyRuleState {
   RuleState policyRuleState = 2;
 }
 
-message PolicyRuleVariable {
-  string policyRuleVariable = 1;
-}
-
-message PolicyRuleValue {
-  string policyRuleValue = 1;
-}
-
 // IETF draft: Framework for Use of ECA (Event Condition Action) in Network Self Management
 //     Source: https://datatracker.ietf.org/doc/draft-bwd-netmod-eca-framework/
 // Event
@@ -61,18 +55,6 @@ message PolicyRuleEvent {
   context.Event event = 1;
 }
 
-// Condition
-message PolicyRuleCondition {
-  PolicyRuleVariable polRuleConditionVar = 1;
-  PolicyRuleValue polRuleConditionVal = 2;
-}
-
-// Action
-message PolicyRuleAction {
-  PolicyRuleVariable polRuleActionVar = 1;
-  PolicyRuleValue polRuleActionVal = 2;
-}
-
 // Policy rule partially complies with IETF’s:
 //     RFC 3060: https://datatracker.ietf.org/doc/html/rfc3060
 //     RFC 3460: https://datatracker.ietf.org/doc/html/rfc3460
@@ -81,16 +63,17 @@ message PolicyRule {
   // Basic policy rule attributes
   PolicyRuleId policyRuleId = 1;
   PolicyRuleType policyRuleType = 2;
-  uint32 PolicyRulePriority = 3;
+  uint32 priority = 3;
 
   // Event-Condition-Action model
-  PolicyRuleEvent event = 4;                             // A single event triggers the policy
-  repeated PolicyRuleCondition polRuleConditionList = 5; // One or more conditions must be met
-  repeated PolicyRuleAction polRuleActionList = 6;       // One or more actions should be applied
-
-  // Affected services and devices
-  repeated context.ServiceId serviceList = 7;
-  repeated context.DeviceId deviceList = 8;
+  PolicyRuleEvent event = 4;                         // A single event triggers the policy
+  repeated PolicyRuleCondition conditionList = 5;    // One or more conditions must be met
+  BooleanOperator booleanOperator = 6;               // Evaluation operator to be used
+  repeated PolicyRuleAction actionList = 7;          // One or more actions should be applied
+
+  // Affected service and devices
+  context.ServiceId serviceId = 8;
+  repeated context.DeviceId deviceList = 9;
 }
 
 // A list of policy rules
diff --git a/src/policy/src/main/proto/policy-action.proto b/src/policy/src/main/proto/policy-action.proto
new file mode 120000
index 000000000..bb1531bd6
--- /dev/null
+++ b/src/policy/src/main/proto/policy-action.proto
@@ -0,0 +1 @@
+../../../../../proto/policy-action.proto
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/policy/Policy.java b/src/policy/target/generated-sources/grpc/policy/Policy.java
index 8386be809..787344739 100644
--- a/src/policy/target/generated-sources/grpc/policy/Policy.java
+++ b/src/policy/target/generated-sources/grpc/policy/Policy.java
@@ -1628,2665 +1628,51 @@ public final class Policy {
 
   }
 
-  public interface PolicyRuleVariableOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleVariable)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>string policyRuleVariable = 1;</code>
-     * @return The policyRuleVariable.
-     */
-    java.lang.String getPolicyRuleVariable();
-    /**
-     * <code>string policyRuleVariable = 1;</code>
-     * @return The bytes for policyRuleVariable.
-     */
-    com.google.protobuf.ByteString
-        getPolicyRuleVariableBytes();
-  }
-  /**
-   * Protobuf type {@code policy.PolicyRuleVariable}
-   */
-  public static final class PolicyRuleVariable extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:policy.PolicyRuleVariable)
-      PolicyRuleVariableOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use PolicyRuleVariable.newBuilder() to construct.
-    private PolicyRuleVariable(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private PolicyRuleVariable() {
-      policyRuleVariable_ = "";
-    }
-
-    @java.lang.Override
-    @SuppressWarnings({"unused"})
-    protected java.lang.Object newInstance(
-        UnusedPrivateParameter unused) {
-      return new PolicyRuleVariable();
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private PolicyRuleVariable(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      if (extensionRegistry == null) {
-        throw new java.lang.NullPointerException();
-      }
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            case 10: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              policyRuleVariable_ = s;
-              break;
-            }
-            default: {
-              if (!parseUnknownField(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return policy.Policy.internal_static_policy_PolicyRuleVariable_descriptor;
-    }
-
-    @java.lang.Override
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return policy.Policy.internal_static_policy_PolicyRuleVariable_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              policy.Policy.PolicyRuleVariable.class, policy.Policy.PolicyRuleVariable.Builder.class);
-    }
-
-    public static final int POLICYRULEVARIABLE_FIELD_NUMBER = 1;
-    private volatile java.lang.Object policyRuleVariable_;
-    /**
-     * <code>string policyRuleVariable = 1;</code>
-     * @return The policyRuleVariable.
-     */
-    @java.lang.Override
-    public java.lang.String getPolicyRuleVariable() {
-      java.lang.Object ref = policyRuleVariable_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        policyRuleVariable_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>string policyRuleVariable = 1;</code>
-     * @return The bytes for policyRuleVariable.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getPolicyRuleVariableBytes() {
-      java.lang.Object ref = policyRuleVariable_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        policyRuleVariable_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    private byte memoizedIsInitialized = -1;
-    @java.lang.Override
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    @java.lang.Override
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      if (!getPolicyRuleVariableBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, policyRuleVariable_);
-      }
-      unknownFields.writeTo(output);
-    }
-
-    @java.lang.Override
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getPolicyRuleVariableBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, policyRuleVariable_);
-      }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
-
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
-      }
-      if (!(obj instanceof policy.Policy.PolicyRuleVariable)) {
-        return super.equals(obj);
-      }
-      policy.Policy.PolicyRuleVariable other = (policy.Policy.PolicyRuleVariable) obj;
-
-      if (!getPolicyRuleVariable()
-          .equals(other.getPolicyRuleVariable())) return false;
-      if (!unknownFields.equals(other.unknownFields)) return false;
-      return true;
-    }
-
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
-      }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      hash = (37 * hash) + POLICYRULEVARIABLE_FIELD_NUMBER;
-      hash = (53 * hash) + getPolicyRuleVariable().hashCode();
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static policy.Policy.PolicyRuleVariable parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleVariable parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleVariable parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleVariable parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleVariable parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleVariable parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleVariable parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleVariable parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleVariable parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleVariable parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleVariable parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleVariable parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-
-    @java.lang.Override
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder() {
-      return DEFAULT_INSTANCE.toBuilder();
-    }
-    public static Builder newBuilder(policy.Policy.PolicyRuleVariable prototype) {
-      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-    }
-    @java.lang.Override
-    public Builder toBuilder() {
-      return this == DEFAULT_INSTANCE
-          ? new Builder() : new Builder().mergeFrom(this);
-    }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code policy.PolicyRuleVariable}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleVariable)
-        policy.Policy.PolicyRuleVariableOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return policy.Policy.internal_static_policy_PolicyRuleVariable_descriptor;
-      }
-
-      @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return policy.Policy.internal_static_policy_PolicyRuleVariable_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                policy.Policy.PolicyRuleVariable.class, policy.Policy.PolicyRuleVariable.Builder.class);
-      }
-
-      // Construct using policy.Policy.PolicyRuleVariable.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-        }
-      }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        policyRuleVariable_ = "";
-
-        return this;
-      }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return policy.Policy.internal_static_policy_PolicyRuleVariable_descriptor;
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleVariable getDefaultInstanceForType() {
-        return policy.Policy.PolicyRuleVariable.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleVariable build() {
-        policy.Policy.PolicyRuleVariable result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleVariable buildPartial() {
-        policy.Policy.PolicyRuleVariable result = new policy.Policy.PolicyRuleVariable(this);
-        result.policyRuleVariable_ = policyRuleVariable_;
-        onBuilt();
-        return result;
-      }
-
-      @java.lang.Override
-      public Builder clone() {
-        return super.clone();
-      }
-      @java.lang.Override
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.setField(field, value);
-      }
-      @java.lang.Override
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return super.clearField(field);
-      }
-      @java.lang.Override
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return super.clearOneof(oneof);
-      }
-      @java.lang.Override
-      public Builder setRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          int index, java.lang.Object value) {
-        return super.setRepeatedField(field, index, value);
-      }
-      @java.lang.Override
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.addRepeatedField(field, value);
-      }
-      @java.lang.Override
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof policy.Policy.PolicyRuleVariable) {
-          return mergeFrom((policy.Policy.PolicyRuleVariable)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(policy.Policy.PolicyRuleVariable other) {
-        if (other == policy.Policy.PolicyRuleVariable.getDefaultInstance()) return this;
-        if (!other.getPolicyRuleVariable().isEmpty()) {
-          policyRuleVariable_ = other.policyRuleVariable_;
-          onChanged();
-        }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
-        return this;
-      }
-
-      @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      @java.lang.Override
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        policy.Policy.PolicyRuleVariable parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (policy.Policy.PolicyRuleVariable) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private java.lang.Object policyRuleVariable_ = "";
-      /**
-       * <code>string policyRuleVariable = 1;</code>
-       * @return The policyRuleVariable.
-       */
-      public java.lang.String getPolicyRuleVariable() {
-        java.lang.Object ref = policyRuleVariable_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          policyRuleVariable_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>string policyRuleVariable = 1;</code>
-       * @return The bytes for policyRuleVariable.
-       */
-      public com.google.protobuf.ByteString
-          getPolicyRuleVariableBytes() {
-        java.lang.Object ref = policyRuleVariable_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          policyRuleVariable_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>string policyRuleVariable = 1;</code>
-       * @param value The policyRuleVariable to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPolicyRuleVariable(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        policyRuleVariable_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string policyRuleVariable = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPolicyRuleVariable() {
-        
-        policyRuleVariable_ = getDefaultInstance().getPolicyRuleVariable();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string policyRuleVariable = 1;</code>
-       * @param value The bytes for policyRuleVariable to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPolicyRuleVariableBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        policyRuleVariable_ = value;
-        onChanged();
-        return this;
-      }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
-      }
-
-      @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleVariable)
-    }
-
-    // @@protoc_insertion_point(class_scope:policy.PolicyRuleVariable)
-    private static final policy.Policy.PolicyRuleVariable DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleVariable();
-    }
-
-    public static policy.Policy.PolicyRuleVariable getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<PolicyRuleVariable>
-        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleVariable>() {
-      @java.lang.Override
-      public PolicyRuleVariable parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new PolicyRuleVariable(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<PolicyRuleVariable> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<PolicyRuleVariable> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public policy.Policy.PolicyRuleVariable getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface PolicyRuleValueOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleValue)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>string policyRuleValue = 1;</code>
-     * @return The policyRuleValue.
-     */
-    java.lang.String getPolicyRuleValue();
-    /**
-     * <code>string policyRuleValue = 1;</code>
-     * @return The bytes for policyRuleValue.
-     */
-    com.google.protobuf.ByteString
-        getPolicyRuleValueBytes();
-  }
-  /**
-   * Protobuf type {@code policy.PolicyRuleValue}
-   */
-  public static final class PolicyRuleValue extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:policy.PolicyRuleValue)
-      PolicyRuleValueOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use PolicyRuleValue.newBuilder() to construct.
-    private PolicyRuleValue(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private PolicyRuleValue() {
-      policyRuleValue_ = "";
-    }
-
-    @java.lang.Override
-    @SuppressWarnings({"unused"})
-    protected java.lang.Object newInstance(
-        UnusedPrivateParameter unused) {
-      return new PolicyRuleValue();
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private PolicyRuleValue(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      if (extensionRegistry == null) {
-        throw new java.lang.NullPointerException();
-      }
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            case 10: {
-              java.lang.String s = input.readStringRequireUtf8();
-
-              policyRuleValue_ = s;
-              break;
-            }
-            default: {
-              if (!parseUnknownField(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return policy.Policy.internal_static_policy_PolicyRuleValue_descriptor;
-    }
-
-    @java.lang.Override
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return policy.Policy.internal_static_policy_PolicyRuleValue_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              policy.Policy.PolicyRuleValue.class, policy.Policy.PolicyRuleValue.Builder.class);
-    }
-
-    public static final int POLICYRULEVALUE_FIELD_NUMBER = 1;
-    private volatile java.lang.Object policyRuleValue_;
-    /**
-     * <code>string policyRuleValue = 1;</code>
-     * @return The policyRuleValue.
-     */
-    @java.lang.Override
-    public java.lang.String getPolicyRuleValue() {
-      java.lang.Object ref = policyRuleValue_;
-      if (ref instanceof java.lang.String) {
-        return (java.lang.String) ref;
-      } else {
-        com.google.protobuf.ByteString bs = 
-            (com.google.protobuf.ByteString) ref;
-        java.lang.String s = bs.toStringUtf8();
-        policyRuleValue_ = s;
-        return s;
-      }
-    }
-    /**
-     * <code>string policyRuleValue = 1;</code>
-     * @return The bytes for policyRuleValue.
-     */
-    @java.lang.Override
-    public com.google.protobuf.ByteString
-        getPolicyRuleValueBytes() {
-      java.lang.Object ref = policyRuleValue_;
-      if (ref instanceof java.lang.String) {
-        com.google.protobuf.ByteString b = 
-            com.google.protobuf.ByteString.copyFromUtf8(
-                (java.lang.String) ref);
-        policyRuleValue_ = b;
-        return b;
-      } else {
-        return (com.google.protobuf.ByteString) ref;
-      }
-    }
-
-    private byte memoizedIsInitialized = -1;
-    @java.lang.Override
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    @java.lang.Override
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      if (!getPolicyRuleValueBytes().isEmpty()) {
-        com.google.protobuf.GeneratedMessageV3.writeString(output, 1, policyRuleValue_);
-      }
-      unknownFields.writeTo(output);
-    }
-
-    @java.lang.Override
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (!getPolicyRuleValueBytes().isEmpty()) {
-        size += com.google.protobuf.GeneratedMessageV3.computeStringSize(1, policyRuleValue_);
-      }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
-
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
-      }
-      if (!(obj instanceof policy.Policy.PolicyRuleValue)) {
-        return super.equals(obj);
-      }
-      policy.Policy.PolicyRuleValue other = (policy.Policy.PolicyRuleValue) obj;
-
-      if (!getPolicyRuleValue()
-          .equals(other.getPolicyRuleValue())) return false;
-      if (!unknownFields.equals(other.unknownFields)) return false;
-      return true;
-    }
-
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
-      }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      hash = (37 * hash) + POLICYRULEVALUE_FIELD_NUMBER;
-      hash = (53 * hash) + getPolicyRuleValue().hashCode();
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static policy.Policy.PolicyRuleValue parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleValue parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleValue parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleValue parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleValue parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleValue parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleValue parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleValue parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleValue parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleValue parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleValue parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleValue parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-
-    @java.lang.Override
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder() {
-      return DEFAULT_INSTANCE.toBuilder();
-    }
-    public static Builder newBuilder(policy.Policy.PolicyRuleValue prototype) {
-      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-    }
-    @java.lang.Override
-    public Builder toBuilder() {
-      return this == DEFAULT_INSTANCE
-          ? new Builder() : new Builder().mergeFrom(this);
-    }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * Protobuf type {@code policy.PolicyRuleValue}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleValue)
-        policy.Policy.PolicyRuleValueOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return policy.Policy.internal_static_policy_PolicyRuleValue_descriptor;
-      }
-
-      @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return policy.Policy.internal_static_policy_PolicyRuleValue_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                policy.Policy.PolicyRuleValue.class, policy.Policy.PolicyRuleValue.Builder.class);
-      }
-
-      // Construct using policy.Policy.PolicyRuleValue.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-        }
-      }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        policyRuleValue_ = "";
-
-        return this;
-      }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return policy.Policy.internal_static_policy_PolicyRuleValue_descriptor;
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleValue getDefaultInstanceForType() {
-        return policy.Policy.PolicyRuleValue.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleValue build() {
-        policy.Policy.PolicyRuleValue result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleValue buildPartial() {
-        policy.Policy.PolicyRuleValue result = new policy.Policy.PolicyRuleValue(this);
-        result.policyRuleValue_ = policyRuleValue_;
-        onBuilt();
-        return result;
-      }
-
-      @java.lang.Override
-      public Builder clone() {
-        return super.clone();
-      }
-      @java.lang.Override
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.setField(field, value);
-      }
-      @java.lang.Override
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return super.clearField(field);
-      }
-      @java.lang.Override
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return super.clearOneof(oneof);
-      }
-      @java.lang.Override
-      public Builder setRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          int index, java.lang.Object value) {
-        return super.setRepeatedField(field, index, value);
-      }
-      @java.lang.Override
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.addRepeatedField(field, value);
-      }
-      @java.lang.Override
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof policy.Policy.PolicyRuleValue) {
-          return mergeFrom((policy.Policy.PolicyRuleValue)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(policy.Policy.PolicyRuleValue other) {
-        if (other == policy.Policy.PolicyRuleValue.getDefaultInstance()) return this;
-        if (!other.getPolicyRuleValue().isEmpty()) {
-          policyRuleValue_ = other.policyRuleValue_;
-          onChanged();
-        }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
-        return this;
-      }
-
-      @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      @java.lang.Override
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        policy.Policy.PolicyRuleValue parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (policy.Policy.PolicyRuleValue) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private java.lang.Object policyRuleValue_ = "";
-      /**
-       * <code>string policyRuleValue = 1;</code>
-       * @return The policyRuleValue.
-       */
-      public java.lang.String getPolicyRuleValue() {
-        java.lang.Object ref = policyRuleValue_;
-        if (!(ref instanceof java.lang.String)) {
-          com.google.protobuf.ByteString bs =
-              (com.google.protobuf.ByteString) ref;
-          java.lang.String s = bs.toStringUtf8();
-          policyRuleValue_ = s;
-          return s;
-        } else {
-          return (java.lang.String) ref;
-        }
-      }
-      /**
-       * <code>string policyRuleValue = 1;</code>
-       * @return The bytes for policyRuleValue.
-       */
-      public com.google.protobuf.ByteString
-          getPolicyRuleValueBytes() {
-        java.lang.Object ref = policyRuleValue_;
-        if (ref instanceof String) {
-          com.google.protobuf.ByteString b = 
-              com.google.protobuf.ByteString.copyFromUtf8(
-                  (java.lang.String) ref);
-          policyRuleValue_ = b;
-          return b;
-        } else {
-          return (com.google.protobuf.ByteString) ref;
-        }
-      }
-      /**
-       * <code>string policyRuleValue = 1;</code>
-       * @param value The policyRuleValue to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPolicyRuleValue(
-          java.lang.String value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  
-        policyRuleValue_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string policyRuleValue = 1;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPolicyRuleValue() {
-        
-        policyRuleValue_ = getDefaultInstance().getPolicyRuleValue();
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>string policyRuleValue = 1;</code>
-       * @param value The bytes for policyRuleValue to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPolicyRuleValueBytes(
-          com.google.protobuf.ByteString value) {
-        if (value == null) {
-    throw new NullPointerException();
-  }
-  checkByteStringIsUtf8(value);
-        
-        policyRuleValue_ = value;
-        onChanged();
-        return this;
-      }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
-      }
-
-      @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleValue)
-    }
-
-    // @@protoc_insertion_point(class_scope:policy.PolicyRuleValue)
-    private static final policy.Policy.PolicyRuleValue DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleValue();
-    }
-
-    public static policy.Policy.PolicyRuleValue getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<PolicyRuleValue>
-        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleValue>() {
-      @java.lang.Override
-      public PolicyRuleValue parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new PolicyRuleValue(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<PolicyRuleValue> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<PolicyRuleValue> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public policy.Policy.PolicyRuleValue getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface PolicyRuleEventOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleEvent)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>.context.Event event = 1;</code>
-     * @return Whether the event field is set.
-     */
-    boolean hasEvent();
-    /**
-     * <code>.context.Event event = 1;</code>
-     * @return The event.
-     */
-    context.ContextOuterClass.Event getEvent();
-    /**
-     * <code>.context.Event event = 1;</code>
-     */
-    context.ContextOuterClass.EventOrBuilder getEventOrBuilder();
-  }
-  /**
-   * <pre>
-   * IETF draft: Framework for Use of ECA (Event Condition Action) in Network Self Management
-   *     Source: https://datatracker.ietf.org/doc/draft-bwd-netmod-eca-framework/
-   * Event
-   * </pre>
-   *
-   * Protobuf type {@code policy.PolicyRuleEvent}
-   */
-  public static final class PolicyRuleEvent extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:policy.PolicyRuleEvent)
-      PolicyRuleEventOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use PolicyRuleEvent.newBuilder() to construct.
-    private PolicyRuleEvent(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private PolicyRuleEvent() {
-    }
-
-    @java.lang.Override
-    @SuppressWarnings({"unused"})
-    protected java.lang.Object newInstance(
-        UnusedPrivateParameter unused) {
-      return new PolicyRuleEvent();
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private PolicyRuleEvent(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      if (extensionRegistry == null) {
-        throw new java.lang.NullPointerException();
-      }
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            case 10: {
-              context.ContextOuterClass.Event.Builder subBuilder = null;
-              if (event_ != null) {
-                subBuilder = event_.toBuilder();
-              }
-              event_ = input.readMessage(context.ContextOuterClass.Event.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(event_);
-                event_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            default: {
-              if (!parseUnknownField(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return policy.Policy.internal_static_policy_PolicyRuleEvent_descriptor;
-    }
-
-    @java.lang.Override
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return policy.Policy.internal_static_policy_PolicyRuleEvent_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              policy.Policy.PolicyRuleEvent.class, policy.Policy.PolicyRuleEvent.Builder.class);
-    }
-
-    public static final int EVENT_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Event event_;
-    /**
-     * <code>.context.Event event = 1;</code>
-     * @return Whether the event field is set.
-     */
-    @java.lang.Override
-    public boolean hasEvent() {
-      return event_ != null;
-    }
-    /**
-     * <code>.context.Event event = 1;</code>
-     * @return The event.
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.Event getEvent() {
-      return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
-    }
-    /**
-     * <code>.context.Event event = 1;</code>
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
-      return getEvent();
-    }
-
-    private byte memoizedIsInitialized = -1;
-    @java.lang.Override
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    @java.lang.Override
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      if (event_ != null) {
-        output.writeMessage(1, getEvent());
-      }
-      unknownFields.writeTo(output);
-    }
-
-    @java.lang.Override
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (event_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getEvent());
-      }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
-
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
-      }
-      if (!(obj instanceof policy.Policy.PolicyRuleEvent)) {
-        return super.equals(obj);
-      }
-      policy.Policy.PolicyRuleEvent other = (policy.Policy.PolicyRuleEvent) obj;
-
-      if (hasEvent() != other.hasEvent()) return false;
-      if (hasEvent()) {
-        if (!getEvent()
-            .equals(other.getEvent())) return false;
-      }
-      if (!unknownFields.equals(other.unknownFields)) return false;
-      return true;
-    }
-
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
-      }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasEvent()) {
-        hash = (37 * hash) + EVENT_FIELD_NUMBER;
-        hash = (53 * hash) + getEvent().hashCode();
-      }
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static policy.Policy.PolicyRuleEvent parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleEvent parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleEvent parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleEvent parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleEvent parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-
-    @java.lang.Override
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder() {
-      return DEFAULT_INSTANCE.toBuilder();
-    }
-    public static Builder newBuilder(policy.Policy.PolicyRuleEvent prototype) {
-      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-    }
-    @java.lang.Override
-    public Builder toBuilder() {
-      return this == DEFAULT_INSTANCE
-          ? new Builder() : new Builder().mergeFrom(this);
-    }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * <pre>
-     * IETF draft: Framework for Use of ECA (Event Condition Action) in Network Self Management
-     *     Source: https://datatracker.ietf.org/doc/draft-bwd-netmod-eca-framework/
-     * Event
-     * </pre>
-     *
-     * Protobuf type {@code policy.PolicyRuleEvent}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleEvent)
-        policy.Policy.PolicyRuleEventOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return policy.Policy.internal_static_policy_PolicyRuleEvent_descriptor;
-      }
-
-      @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return policy.Policy.internal_static_policy_PolicyRuleEvent_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                policy.Policy.PolicyRuleEvent.class, policy.Policy.PolicyRuleEvent.Builder.class);
-      }
-
-      // Construct using policy.Policy.PolicyRuleEvent.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-        }
-      }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        if (eventBuilder_ == null) {
-          event_ = null;
-        } else {
-          event_ = null;
-          eventBuilder_ = null;
-        }
-        return this;
-      }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return policy.Policy.internal_static_policy_PolicyRuleEvent_descriptor;
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleEvent getDefaultInstanceForType() {
-        return policy.Policy.PolicyRuleEvent.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleEvent build() {
-        policy.Policy.PolicyRuleEvent result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleEvent buildPartial() {
-        policy.Policy.PolicyRuleEvent result = new policy.Policy.PolicyRuleEvent(this);
-        if (eventBuilder_ == null) {
-          result.event_ = event_;
-        } else {
-          result.event_ = eventBuilder_.build();
-        }
-        onBuilt();
-        return result;
-      }
-
-      @java.lang.Override
-      public Builder clone() {
-        return super.clone();
-      }
-      @java.lang.Override
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.setField(field, value);
-      }
-      @java.lang.Override
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return super.clearField(field);
-      }
-      @java.lang.Override
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return super.clearOneof(oneof);
-      }
-      @java.lang.Override
-      public Builder setRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          int index, java.lang.Object value) {
-        return super.setRepeatedField(field, index, value);
-      }
-      @java.lang.Override
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.addRepeatedField(field, value);
-      }
-      @java.lang.Override
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof policy.Policy.PolicyRuleEvent) {
-          return mergeFrom((policy.Policy.PolicyRuleEvent)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(policy.Policy.PolicyRuleEvent other) {
-        if (other == policy.Policy.PolicyRuleEvent.getDefaultInstance()) return this;
-        if (other.hasEvent()) {
-          mergeEvent(other.getEvent());
-        }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
-        return this;
-      }
-
-      @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      @java.lang.Override
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        policy.Policy.PolicyRuleEvent parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (policy.Policy.PolicyRuleEvent) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private context.ContextOuterClass.Event event_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> eventBuilder_;
-      /**
-       * <code>.context.Event event = 1;</code>
-       * @return Whether the event field is set.
-       */
-      public boolean hasEvent() {
-        return eventBuilder_ != null || event_ != null;
-      }
-      /**
-       * <code>.context.Event event = 1;</code>
-       * @return The event.
-       */
-      public context.ContextOuterClass.Event getEvent() {
-        if (eventBuilder_ == null) {
-          return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
-        } else {
-          return eventBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.context.Event event = 1;</code>
-       */
-      public Builder setEvent(context.ContextOuterClass.Event value) {
-        if (eventBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          event_ = value;
-          onChanged();
-        } else {
-          eventBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.Event event = 1;</code>
-       */
-      public Builder setEvent(
-          context.ContextOuterClass.Event.Builder builderForValue) {
-        if (eventBuilder_ == null) {
-          event_ = builderForValue.build();
-          onChanged();
-        } else {
-          eventBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.Event event = 1;</code>
-       */
-      public Builder mergeEvent(context.ContextOuterClass.Event value) {
-        if (eventBuilder_ == null) {
-          if (event_ != null) {
-            event_ =
-              context.ContextOuterClass.Event.newBuilder(event_).mergeFrom(value).buildPartial();
-          } else {
-            event_ = value;
-          }
-          onChanged();
-        } else {
-          eventBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.Event event = 1;</code>
-       */
-      public Builder clearEvent() {
-        if (eventBuilder_ == null) {
-          event_ = null;
-          onChanged();
-        } else {
-          event_ = null;
-          eventBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.Event event = 1;</code>
-       */
-      public context.ContextOuterClass.Event.Builder getEventBuilder() {
-        
-        onChanged();
-        return getEventFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.Event event = 1;</code>
-       */
-      public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
-        if (eventBuilder_ != null) {
-          return eventBuilder_.getMessageOrBuilder();
-        } else {
-          return event_ == null ?
-              context.ContextOuterClass.Event.getDefaultInstance() : event_;
-        }
-      }
-      /**
-       * <code>.context.Event event = 1;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> 
-          getEventFieldBuilder() {
-        if (eventBuilder_ == null) {
-          eventBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder>(
-                  getEvent(),
-                  getParentForChildren(),
-                  isClean());
-          event_ = null;
-        }
-        return eventBuilder_;
-      }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
-      }
-
-      @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleEvent)
-    }
-
-    // @@protoc_insertion_point(class_scope:policy.PolicyRuleEvent)
-    private static final policy.Policy.PolicyRuleEvent DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleEvent();
-    }
-
-    public static policy.Policy.PolicyRuleEvent getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<PolicyRuleEvent>
-        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleEvent>() {
-      @java.lang.Override
-      public PolicyRuleEvent parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new PolicyRuleEvent(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<PolicyRuleEvent> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<PolicyRuleEvent> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public policy.Policy.PolicyRuleEvent getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface PolicyRuleConditionOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleCondition)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-     * @return Whether the polRuleConditionVar field is set.
-     */
-    boolean hasPolRuleConditionVar();
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-     * @return The polRuleConditionVar.
-     */
-    policy.Policy.PolicyRuleVariable getPolRuleConditionVar();
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-     */
-    policy.Policy.PolicyRuleVariableOrBuilder getPolRuleConditionVarOrBuilder();
-
-    /**
-     * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-     * @return Whether the polRuleConditionVal field is set.
-     */
-    boolean hasPolRuleConditionVal();
-    /**
-     * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-     * @return The polRuleConditionVal.
-     */
-    policy.Policy.PolicyRuleValue getPolRuleConditionVal();
-    /**
-     * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-     */
-    policy.Policy.PolicyRuleValueOrBuilder getPolRuleConditionValOrBuilder();
-  }
-  /**
-   * <pre>
-   * Condition
-   * </pre>
-   *
-   * Protobuf type {@code policy.PolicyRuleCondition}
-   */
-  public static final class PolicyRuleCondition extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:policy.PolicyRuleCondition)
-      PolicyRuleConditionOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use PolicyRuleCondition.newBuilder() to construct.
-    private PolicyRuleCondition(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private PolicyRuleCondition() {
-    }
-
-    @java.lang.Override
-    @SuppressWarnings({"unused"})
-    protected java.lang.Object newInstance(
-        UnusedPrivateParameter unused) {
-      return new PolicyRuleCondition();
-    }
-
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private PolicyRuleCondition(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      if (extensionRegistry == null) {
-        throw new java.lang.NullPointerException();
-      }
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            case 10: {
-              policy.Policy.PolicyRuleVariable.Builder subBuilder = null;
-              if (polRuleConditionVar_ != null) {
-                subBuilder = polRuleConditionVar_.toBuilder();
-              }
-              polRuleConditionVar_ = input.readMessage(policy.Policy.PolicyRuleVariable.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(polRuleConditionVar_);
-                polRuleConditionVar_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            case 18: {
-              policy.Policy.PolicyRuleValue.Builder subBuilder = null;
-              if (polRuleConditionVal_ != null) {
-                subBuilder = polRuleConditionVal_.toBuilder();
-              }
-              polRuleConditionVal_ = input.readMessage(policy.Policy.PolicyRuleValue.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(polRuleConditionVal_);
-                polRuleConditionVal_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            default: {
-              if (!parseUnknownField(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
-          }
-        }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e).setUnfinishedMessage(this);
-      } finally {
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
-      }
-    }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return policy.Policy.internal_static_policy_PolicyRuleCondition_descriptor;
-    }
-
-    @java.lang.Override
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return policy.Policy.internal_static_policy_PolicyRuleCondition_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              policy.Policy.PolicyRuleCondition.class, policy.Policy.PolicyRuleCondition.Builder.class);
-    }
-
-    public static final int POLRULECONDITIONVAR_FIELD_NUMBER = 1;
-    private policy.Policy.PolicyRuleVariable polRuleConditionVar_;
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-     * @return Whether the polRuleConditionVar field is set.
-     */
-    @java.lang.Override
-    public boolean hasPolRuleConditionVar() {
-      return polRuleConditionVar_ != null;
-    }
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-     * @return The polRuleConditionVar.
-     */
-    @java.lang.Override
-    public policy.Policy.PolicyRuleVariable getPolRuleConditionVar() {
-      return polRuleConditionVar_ == null ? policy.Policy.PolicyRuleVariable.getDefaultInstance() : polRuleConditionVar_;
-    }
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-     */
-    @java.lang.Override
-    public policy.Policy.PolicyRuleVariableOrBuilder getPolRuleConditionVarOrBuilder() {
-      return getPolRuleConditionVar();
-    }
-
-    public static final int POLRULECONDITIONVAL_FIELD_NUMBER = 2;
-    private policy.Policy.PolicyRuleValue polRuleConditionVal_;
-    /**
-     * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-     * @return Whether the polRuleConditionVal field is set.
-     */
-    @java.lang.Override
-    public boolean hasPolRuleConditionVal() {
-      return polRuleConditionVal_ != null;
-    }
-    /**
-     * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-     * @return The polRuleConditionVal.
-     */
-    @java.lang.Override
-    public policy.Policy.PolicyRuleValue getPolRuleConditionVal() {
-      return polRuleConditionVal_ == null ? policy.Policy.PolicyRuleValue.getDefaultInstance() : polRuleConditionVal_;
-    }
-    /**
-     * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-     */
-    @java.lang.Override
-    public policy.Policy.PolicyRuleValueOrBuilder getPolRuleConditionValOrBuilder() {
-      return getPolRuleConditionVal();
-    }
-
-    private byte memoizedIsInitialized = -1;
-    @java.lang.Override
-    public final boolean isInitialized() {
-      byte isInitialized = memoizedIsInitialized;
-      if (isInitialized == 1) return true;
-      if (isInitialized == 0) return false;
-
-      memoizedIsInitialized = 1;
-      return true;
-    }
-
-    @java.lang.Override
-    public void writeTo(com.google.protobuf.CodedOutputStream output)
-                        throws java.io.IOException {
-      if (polRuleConditionVar_ != null) {
-        output.writeMessage(1, getPolRuleConditionVar());
-      }
-      if (polRuleConditionVal_ != null) {
-        output.writeMessage(2, getPolRuleConditionVal());
-      }
-      unknownFields.writeTo(output);
-    }
-
-    @java.lang.Override
-    public int getSerializedSize() {
-      int size = memoizedSize;
-      if (size != -1) return size;
-
-      size = 0;
-      if (polRuleConditionVar_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getPolRuleConditionVar());
-      }
-      if (polRuleConditionVal_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, getPolRuleConditionVal());
-      }
-      size += unknownFields.getSerializedSize();
-      memoizedSize = size;
-      return size;
-    }
-
-    @java.lang.Override
-    public boolean equals(final java.lang.Object obj) {
-      if (obj == this) {
-       return true;
-      }
-      if (!(obj instanceof policy.Policy.PolicyRuleCondition)) {
-        return super.equals(obj);
-      }
-      policy.Policy.PolicyRuleCondition other = (policy.Policy.PolicyRuleCondition) obj;
-
-      if (hasPolRuleConditionVar() != other.hasPolRuleConditionVar()) return false;
-      if (hasPolRuleConditionVar()) {
-        if (!getPolRuleConditionVar()
-            .equals(other.getPolRuleConditionVar())) return false;
-      }
-      if (hasPolRuleConditionVal() != other.hasPolRuleConditionVal()) return false;
-      if (hasPolRuleConditionVal()) {
-        if (!getPolRuleConditionVal()
-            .equals(other.getPolRuleConditionVal())) return false;
-      }
-      if (!unknownFields.equals(other.unknownFields)) return false;
-      return true;
-    }
-
-    @java.lang.Override
-    public int hashCode() {
-      if (memoizedHashCode != 0) {
-        return memoizedHashCode;
-      }
-      int hash = 41;
-      hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasPolRuleConditionVar()) {
-        hash = (37 * hash) + POLRULECONDITIONVAR_FIELD_NUMBER;
-        hash = (53 * hash) + getPolRuleConditionVar().hashCode();
-      }
-      if (hasPolRuleConditionVal()) {
-        hash = (37 * hash) + POLRULECONDITIONVAL_FIELD_NUMBER;
-        hash = (53 * hash) + getPolRuleConditionVal().hashCode();
-      }
-      hash = (29 * hash) + unknownFields.hashCode();
-      memoizedHashCode = hash;
-      return hash;
-    }
-
-    public static policy.Policy.PolicyRuleCondition parseFrom(
-        java.nio.ByteBuffer data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleCondition parseFrom(
-        java.nio.ByteBuffer data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleCondition parseFrom(
-        com.google.protobuf.ByteString data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleCondition parseFrom(
-        com.google.protobuf.ByteString data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleCondition parseFrom(byte[] data)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data);
-    }
-    public static policy.Policy.PolicyRuleCondition parseFrom(
-        byte[] data,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      return PARSER.parseFrom(data, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleCondition parseFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleCondition parseFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleCondition parseDelimitedFrom(java.io.InputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleCondition parseDelimitedFrom(
-        java.io.InputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
-    }
-    public static policy.Policy.PolicyRuleCondition parseFrom(
-        com.google.protobuf.CodedInputStream input)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input);
-    }
-    public static policy.Policy.PolicyRuleCondition parseFrom(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws java.io.IOException {
-      return com.google.protobuf.GeneratedMessageV3
-          .parseWithIOException(PARSER, input, extensionRegistry);
-    }
-
-    @java.lang.Override
-    public Builder newBuilderForType() { return newBuilder(); }
-    public static Builder newBuilder() {
-      return DEFAULT_INSTANCE.toBuilder();
-    }
-    public static Builder newBuilder(policy.Policy.PolicyRuleCondition prototype) {
-      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
-    }
-    @java.lang.Override
-    public Builder toBuilder() {
-      return this == DEFAULT_INSTANCE
-          ? new Builder() : new Builder().mergeFrom(this);
-    }
-
-    @java.lang.Override
-    protected Builder newBuilderForType(
-        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-      Builder builder = new Builder(parent);
-      return builder;
-    }
-    /**
-     * <pre>
-     * Condition
-     * </pre>
-     *
-     * Protobuf type {@code policy.PolicyRuleCondition}
-     */
-    public static final class Builder extends
-        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleCondition)
-        policy.Policy.PolicyRuleConditionOrBuilder {
-      public static final com.google.protobuf.Descriptors.Descriptor
-          getDescriptor() {
-        return policy.Policy.internal_static_policy_PolicyRuleCondition_descriptor;
-      }
-
-      @java.lang.Override
-      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-          internalGetFieldAccessorTable() {
-        return policy.Policy.internal_static_policy_PolicyRuleCondition_fieldAccessorTable
-            .ensureFieldAccessorsInitialized(
-                policy.Policy.PolicyRuleCondition.class, policy.Policy.PolicyRuleCondition.Builder.class);
-      }
-
-      // Construct using policy.Policy.PolicyRuleCondition.newBuilder()
-      private Builder() {
-        maybeForceBuilderInitialization();
-      }
-
-      private Builder(
-          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
-        super(parent);
-        maybeForceBuilderInitialization();
-      }
-      private void maybeForceBuilderInitialization() {
-        if (com.google.protobuf.GeneratedMessageV3
-                .alwaysUseFieldBuilders) {
-        }
-      }
-      @java.lang.Override
-      public Builder clear() {
-        super.clear();
-        if (polRuleConditionVarBuilder_ == null) {
-          polRuleConditionVar_ = null;
-        } else {
-          polRuleConditionVar_ = null;
-          polRuleConditionVarBuilder_ = null;
-        }
-        if (polRuleConditionValBuilder_ == null) {
-          polRuleConditionVal_ = null;
-        } else {
-          polRuleConditionVal_ = null;
-          polRuleConditionValBuilder_ = null;
-        }
-        return this;
-      }
-
-      @java.lang.Override
-      public com.google.protobuf.Descriptors.Descriptor
-          getDescriptorForType() {
-        return policy.Policy.internal_static_policy_PolicyRuleCondition_descriptor;
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleCondition getDefaultInstanceForType() {
-        return policy.Policy.PolicyRuleCondition.getDefaultInstance();
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleCondition build() {
-        policy.Policy.PolicyRuleCondition result = buildPartial();
-        if (!result.isInitialized()) {
-          throw newUninitializedMessageException(result);
-        }
-        return result;
-      }
-
-      @java.lang.Override
-      public policy.Policy.PolicyRuleCondition buildPartial() {
-        policy.Policy.PolicyRuleCondition result = new policy.Policy.PolicyRuleCondition(this);
-        if (polRuleConditionVarBuilder_ == null) {
-          result.polRuleConditionVar_ = polRuleConditionVar_;
-        } else {
-          result.polRuleConditionVar_ = polRuleConditionVarBuilder_.build();
-        }
-        if (polRuleConditionValBuilder_ == null) {
-          result.polRuleConditionVal_ = polRuleConditionVal_;
-        } else {
-          result.polRuleConditionVal_ = polRuleConditionValBuilder_.build();
-        }
-        onBuilt();
-        return result;
-      }
-
-      @java.lang.Override
-      public Builder clone() {
-        return super.clone();
-      }
-      @java.lang.Override
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.setField(field, value);
-      }
-      @java.lang.Override
-      public Builder clearField(
-          com.google.protobuf.Descriptors.FieldDescriptor field) {
-        return super.clearField(field);
-      }
-      @java.lang.Override
-      public Builder clearOneof(
-          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
-        return super.clearOneof(oneof);
-      }
-      @java.lang.Override
-      public Builder setRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          int index, java.lang.Object value) {
-        return super.setRepeatedField(field, index, value);
-      }
-      @java.lang.Override
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.addRepeatedField(field, value);
-      }
-      @java.lang.Override
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof policy.Policy.PolicyRuleCondition) {
-          return mergeFrom((policy.Policy.PolicyRuleCondition)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(policy.Policy.PolicyRuleCondition other) {
-        if (other == policy.Policy.PolicyRuleCondition.getDefaultInstance()) return this;
-        if (other.hasPolRuleConditionVar()) {
-          mergePolRuleConditionVar(other.getPolRuleConditionVar());
-        }
-        if (other.hasPolRuleConditionVal()) {
-          mergePolRuleConditionVal(other.getPolRuleConditionVal());
-        }
-        this.mergeUnknownFields(other.unknownFields);
-        onChanged();
-        return this;
-      }
-
-      @java.lang.Override
-      public final boolean isInitialized() {
-        return true;
-      }
-
-      @java.lang.Override
-      public Builder mergeFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws java.io.IOException {
-        policy.Policy.PolicyRuleCondition parsedMessage = null;
-        try {
-          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
-        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (policy.Policy.PolicyRuleCondition) e.getUnfinishedMessage();
-          throw e.unwrapIOException();
-        } finally {
-          if (parsedMessage != null) {
-            mergeFrom(parsedMessage);
-          }
-        }
-        return this;
-      }
-
-      private policy.Policy.PolicyRuleVariable polRuleConditionVar_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleVariable, policy.Policy.PolicyRuleVariable.Builder, policy.Policy.PolicyRuleVariableOrBuilder> polRuleConditionVarBuilder_;
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-       * @return Whether the polRuleConditionVar field is set.
-       */
-      public boolean hasPolRuleConditionVar() {
-        return polRuleConditionVarBuilder_ != null || polRuleConditionVar_ != null;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-       * @return The polRuleConditionVar.
-       */
-      public policy.Policy.PolicyRuleVariable getPolRuleConditionVar() {
-        if (polRuleConditionVarBuilder_ == null) {
-          return polRuleConditionVar_ == null ? policy.Policy.PolicyRuleVariable.getDefaultInstance() : polRuleConditionVar_;
-        } else {
-          return polRuleConditionVarBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-       */
-      public Builder setPolRuleConditionVar(policy.Policy.PolicyRuleVariable value) {
-        if (polRuleConditionVarBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          polRuleConditionVar_ = value;
-          onChanged();
-        } else {
-          polRuleConditionVarBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-       */
-      public Builder setPolRuleConditionVar(
-          policy.Policy.PolicyRuleVariable.Builder builderForValue) {
-        if (polRuleConditionVarBuilder_ == null) {
-          polRuleConditionVar_ = builderForValue.build();
-          onChanged();
-        } else {
-          polRuleConditionVarBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-       */
-      public Builder mergePolRuleConditionVar(policy.Policy.PolicyRuleVariable value) {
-        if (polRuleConditionVarBuilder_ == null) {
-          if (polRuleConditionVar_ != null) {
-            polRuleConditionVar_ =
-              policy.Policy.PolicyRuleVariable.newBuilder(polRuleConditionVar_).mergeFrom(value).buildPartial();
-          } else {
-            polRuleConditionVar_ = value;
-          }
-          onChanged();
-        } else {
-          polRuleConditionVarBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-       */
-      public Builder clearPolRuleConditionVar() {
-        if (polRuleConditionVarBuilder_ == null) {
-          polRuleConditionVar_ = null;
-          onChanged();
-        } else {
-          polRuleConditionVar_ = null;
-          polRuleConditionVarBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-       */
-      public policy.Policy.PolicyRuleVariable.Builder getPolRuleConditionVarBuilder() {
-        
-        onChanged();
-        return getPolRuleConditionVarFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-       */
-      public policy.Policy.PolicyRuleVariableOrBuilder getPolRuleConditionVarOrBuilder() {
-        if (polRuleConditionVarBuilder_ != null) {
-          return polRuleConditionVarBuilder_.getMessageOrBuilder();
-        } else {
-          return polRuleConditionVar_ == null ?
-              policy.Policy.PolicyRuleVariable.getDefaultInstance() : polRuleConditionVar_;
-        }
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleConditionVar = 1;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleVariable, policy.Policy.PolicyRuleVariable.Builder, policy.Policy.PolicyRuleVariableOrBuilder> 
-          getPolRuleConditionVarFieldBuilder() {
-        if (polRuleConditionVarBuilder_ == null) {
-          polRuleConditionVarBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              policy.Policy.PolicyRuleVariable, policy.Policy.PolicyRuleVariable.Builder, policy.Policy.PolicyRuleVariableOrBuilder>(
-                  getPolRuleConditionVar(),
-                  getParentForChildren(),
-                  isClean());
-          polRuleConditionVar_ = null;
-        }
-        return polRuleConditionVarBuilder_;
-      }
-
-      private policy.Policy.PolicyRuleValue polRuleConditionVal_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleValue, policy.Policy.PolicyRuleValue.Builder, policy.Policy.PolicyRuleValueOrBuilder> polRuleConditionValBuilder_;
-      /**
-       * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-       * @return Whether the polRuleConditionVal field is set.
-       */
-      public boolean hasPolRuleConditionVal() {
-        return polRuleConditionValBuilder_ != null || polRuleConditionVal_ != null;
-      }
-      /**
-       * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-       * @return The polRuleConditionVal.
-       */
-      public policy.Policy.PolicyRuleValue getPolRuleConditionVal() {
-        if (polRuleConditionValBuilder_ == null) {
-          return polRuleConditionVal_ == null ? policy.Policy.PolicyRuleValue.getDefaultInstance() : polRuleConditionVal_;
-        } else {
-          return polRuleConditionValBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-       */
-      public Builder setPolRuleConditionVal(policy.Policy.PolicyRuleValue value) {
-        if (polRuleConditionValBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          polRuleConditionVal_ = value;
-          onChanged();
-        } else {
-          polRuleConditionValBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-       */
-      public Builder setPolRuleConditionVal(
-          policy.Policy.PolicyRuleValue.Builder builderForValue) {
-        if (polRuleConditionValBuilder_ == null) {
-          polRuleConditionVal_ = builderForValue.build();
-          onChanged();
-        } else {
-          polRuleConditionValBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-       */
-      public Builder mergePolRuleConditionVal(policy.Policy.PolicyRuleValue value) {
-        if (polRuleConditionValBuilder_ == null) {
-          if (polRuleConditionVal_ != null) {
-            polRuleConditionVal_ =
-              policy.Policy.PolicyRuleValue.newBuilder(polRuleConditionVal_).mergeFrom(value).buildPartial();
-          } else {
-            polRuleConditionVal_ = value;
-          }
-          onChanged();
-        } else {
-          polRuleConditionValBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-       */
-      public Builder clearPolRuleConditionVal() {
-        if (polRuleConditionValBuilder_ == null) {
-          polRuleConditionVal_ = null;
-          onChanged();
-        } else {
-          polRuleConditionVal_ = null;
-          polRuleConditionValBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-       */
-      public policy.Policy.PolicyRuleValue.Builder getPolRuleConditionValBuilder() {
-        
-        onChanged();
-        return getPolRuleConditionValFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-       */
-      public policy.Policy.PolicyRuleValueOrBuilder getPolRuleConditionValOrBuilder() {
-        if (polRuleConditionValBuilder_ != null) {
-          return polRuleConditionValBuilder_.getMessageOrBuilder();
-        } else {
-          return polRuleConditionVal_ == null ?
-              policy.Policy.PolicyRuleValue.getDefaultInstance() : polRuleConditionVal_;
-        }
-      }
-      /**
-       * <code>.policy.PolicyRuleValue polRuleConditionVal = 2;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleValue, policy.Policy.PolicyRuleValue.Builder, policy.Policy.PolicyRuleValueOrBuilder> 
-          getPolRuleConditionValFieldBuilder() {
-        if (polRuleConditionValBuilder_ == null) {
-          polRuleConditionValBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              policy.Policy.PolicyRuleValue, policy.Policy.PolicyRuleValue.Builder, policy.Policy.PolicyRuleValueOrBuilder>(
-                  getPolRuleConditionVal(),
-                  getParentForChildren(),
-                  isClean());
-          polRuleConditionVal_ = null;
-        }
-        return polRuleConditionValBuilder_;
-      }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
-      }
-
-      @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
-      }
-
-
-      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleCondition)
-    }
-
-    // @@protoc_insertion_point(class_scope:policy.PolicyRuleCondition)
-    private static final policy.Policy.PolicyRuleCondition DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleCondition();
-    }
-
-    public static policy.Policy.PolicyRuleCondition getDefaultInstance() {
-      return DEFAULT_INSTANCE;
-    }
-
-    private static final com.google.protobuf.Parser<PolicyRuleCondition>
-        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleCondition>() {
-      @java.lang.Override
-      public PolicyRuleCondition parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new PolicyRuleCondition(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<PolicyRuleCondition> parser() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public com.google.protobuf.Parser<PolicyRuleCondition> getParserForType() {
-      return PARSER;
-    }
-
-    @java.lang.Override
-    public policy.Policy.PolicyRuleCondition getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
-    }
-
-  }
-
-  public interface PolicyRuleActionOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleAction)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-     * @return Whether the polRuleActionVar field is set.
-     */
-    boolean hasPolRuleActionVar();
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-     * @return The polRuleActionVar.
-     */
-    policy.Policy.PolicyRuleVariable getPolRuleActionVar();
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-     */
-    policy.Policy.PolicyRuleVariableOrBuilder getPolRuleActionVarOrBuilder();
+  public interface PolicyRuleEventOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleEvent)
+      com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
-     * @return Whether the polRuleActionVal field is set.
+     * <code>.context.Event event = 1;</code>
+     * @return Whether the event field is set.
      */
-    boolean hasPolRuleActionVal();
+    boolean hasEvent();
     /**
-     * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
-     * @return The polRuleActionVal.
+     * <code>.context.Event event = 1;</code>
+     * @return The event.
      */
-    policy.Policy.PolicyRuleValue getPolRuleActionVal();
+    context.ContextOuterClass.Event getEvent();
     /**
-     * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
+     * <code>.context.Event event = 1;</code>
      */
-    policy.Policy.PolicyRuleValueOrBuilder getPolRuleActionValOrBuilder();
+    context.ContextOuterClass.EventOrBuilder getEventOrBuilder();
   }
   /**
    * <pre>
-   * Action
+   * IETF draft: Framework for Use of ECA (Event Condition Action) in Network Self Management
+   *     Source: https://datatracker.ietf.org/doc/draft-bwd-netmod-eca-framework/
+   * Event
    * </pre>
    *
-   * Protobuf type {@code policy.PolicyRuleAction}
+   * Protobuf type {@code policy.PolicyRuleEvent}
    */
-  public static final class PolicyRuleAction extends
+  public static final class PolicyRuleEvent extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:policy.PolicyRuleAction)
-      PolicyRuleActionOrBuilder {
+      // @@protoc_insertion_point(message_implements:policy.PolicyRuleEvent)
+      PolicyRuleEventOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use PolicyRuleAction.newBuilder() to construct.
-    private PolicyRuleAction(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use PolicyRuleEvent.newBuilder() to construct.
+    private PolicyRuleEvent(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private PolicyRuleAction() {
+    private PolicyRuleEvent() {
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new PolicyRuleAction();
+      return new PolicyRuleEvent();
     }
 
     @java.lang.Override
@@ -4294,7 +1680,7 @@ public final class Policy {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private PolicyRuleAction(
+    private PolicyRuleEvent(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -4313,27 +1699,14 @@ public final class Policy {
               done = true;
               break;
             case 10: {
-              policy.Policy.PolicyRuleVariable.Builder subBuilder = null;
-              if (polRuleActionVar_ != null) {
-                subBuilder = polRuleActionVar_.toBuilder();
-              }
-              polRuleActionVar_ = input.readMessage(policy.Policy.PolicyRuleVariable.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(polRuleActionVar_);
-                polRuleActionVar_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            case 18: {
-              policy.Policy.PolicyRuleValue.Builder subBuilder = null;
-              if (polRuleActionVal_ != null) {
-                subBuilder = polRuleActionVal_.toBuilder();
+              context.ContextOuterClass.Event.Builder subBuilder = null;
+              if (event_ != null) {
+                subBuilder = event_.toBuilder();
               }
-              polRuleActionVal_ = input.readMessage(policy.Policy.PolicyRuleValue.parser(), extensionRegistry);
+              event_ = input.readMessage(context.ContextOuterClass.Event.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(polRuleActionVal_);
-                polRuleActionVal_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(event_);
+                event_ = subBuilder.buildPartial();
               }
 
               break;
@@ -4359,67 +1732,41 @@ public final class Policy {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return policy.Policy.internal_static_policy_PolicyRuleAction_descriptor;
+      return policy.Policy.internal_static_policy_PolicyRuleEvent_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return policy.Policy.internal_static_policy_PolicyRuleAction_fieldAccessorTable
+      return policy.Policy.internal_static_policy_PolicyRuleEvent_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              policy.Policy.PolicyRuleAction.class, policy.Policy.PolicyRuleAction.Builder.class);
-    }
-
-    public static final int POLRULEACTIONVAR_FIELD_NUMBER = 1;
-    private policy.Policy.PolicyRuleVariable polRuleActionVar_;
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-     * @return Whether the polRuleActionVar field is set.
-     */
-    @java.lang.Override
-    public boolean hasPolRuleActionVar() {
-      return polRuleActionVar_ != null;
-    }
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-     * @return The polRuleActionVar.
-     */
-    @java.lang.Override
-    public policy.Policy.PolicyRuleVariable getPolRuleActionVar() {
-      return polRuleActionVar_ == null ? policy.Policy.PolicyRuleVariable.getDefaultInstance() : polRuleActionVar_;
-    }
-    /**
-     * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-     */
-    @java.lang.Override
-    public policy.Policy.PolicyRuleVariableOrBuilder getPolRuleActionVarOrBuilder() {
-      return getPolRuleActionVar();
+              policy.Policy.PolicyRuleEvent.class, policy.Policy.PolicyRuleEvent.Builder.class);
     }
 
-    public static final int POLRULEACTIONVAL_FIELD_NUMBER = 2;
-    private policy.Policy.PolicyRuleValue polRuleActionVal_;
+    public static final int EVENT_FIELD_NUMBER = 1;
+    private context.ContextOuterClass.Event event_;
     /**
-     * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
-     * @return Whether the polRuleActionVal field is set.
+     * <code>.context.Event event = 1;</code>
+     * @return Whether the event field is set.
      */
     @java.lang.Override
-    public boolean hasPolRuleActionVal() {
-      return polRuleActionVal_ != null;
+    public boolean hasEvent() {
+      return event_ != null;
     }
     /**
-     * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
-     * @return The polRuleActionVal.
+     * <code>.context.Event event = 1;</code>
+     * @return The event.
      */
     @java.lang.Override
-    public policy.Policy.PolicyRuleValue getPolRuleActionVal() {
-      return polRuleActionVal_ == null ? policy.Policy.PolicyRuleValue.getDefaultInstance() : polRuleActionVal_;
+    public context.ContextOuterClass.Event getEvent() {
+      return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
     }
     /**
-     * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
+     * <code>.context.Event event = 1;</code>
      */
     @java.lang.Override
-    public policy.Policy.PolicyRuleValueOrBuilder getPolRuleActionValOrBuilder() {
-      return getPolRuleActionVal();
+    public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
+      return getEvent();
     }
 
     private byte memoizedIsInitialized = -1;
@@ -4436,11 +1783,8 @@ public final class Policy {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (polRuleActionVar_ != null) {
-        output.writeMessage(1, getPolRuleActionVar());
-      }
-      if (polRuleActionVal_ != null) {
-        output.writeMessage(2, getPolRuleActionVal());
+      if (event_ != null) {
+        output.writeMessage(1, getEvent());
       }
       unknownFields.writeTo(output);
     }
@@ -4451,13 +1795,9 @@ public final class Policy {
       if (size != -1) return size;
 
       size = 0;
-      if (polRuleActionVar_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getPolRuleActionVar());
-      }
-      if (polRuleActionVal_ != null) {
+      if (event_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(2, getPolRuleActionVal());
+          .computeMessageSize(1, getEvent());
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -4469,20 +1809,15 @@ public final class Policy {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof policy.Policy.PolicyRuleAction)) {
+      if (!(obj instanceof policy.Policy.PolicyRuleEvent)) {
         return super.equals(obj);
       }
-      policy.Policy.PolicyRuleAction other = (policy.Policy.PolicyRuleAction) obj;
+      policy.Policy.PolicyRuleEvent other = (policy.Policy.PolicyRuleEvent) obj;
 
-      if (hasPolRuleActionVar() != other.hasPolRuleActionVar()) return false;
-      if (hasPolRuleActionVar()) {
-        if (!getPolRuleActionVar()
-            .equals(other.getPolRuleActionVar())) return false;
-      }
-      if (hasPolRuleActionVal() != other.hasPolRuleActionVal()) return false;
-      if (hasPolRuleActionVal()) {
-        if (!getPolRuleActionVal()
-            .equals(other.getPolRuleActionVal())) return false;
+      if (hasEvent() != other.hasEvent()) return false;
+      if (hasEvent()) {
+        if (!getEvent()
+            .equals(other.getEvent())) return false;
       }
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
@@ -4495,82 +1830,78 @@ public final class Policy {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasPolRuleActionVar()) {
-        hash = (37 * hash) + POLRULEACTIONVAR_FIELD_NUMBER;
-        hash = (53 * hash) + getPolRuleActionVar().hashCode();
-      }
-      if (hasPolRuleActionVal()) {
-        hash = (37 * hash) + POLRULEACTIONVAL_FIELD_NUMBER;
-        hash = (53 * hash) + getPolRuleActionVal().hashCode();
+      if (hasEvent()) {
+        hash = (37 * hash) + EVENT_FIELD_NUMBER;
+        hash = (53 * hash) + getEvent().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static policy.Policy.PolicyRuleAction parseFrom(
+    public static policy.Policy.PolicyRuleEvent parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRuleAction parseFrom(
+    public static policy.Policy.PolicyRuleEvent parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleAction parseFrom(
+    public static policy.Policy.PolicyRuleEvent parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRuleAction parseFrom(
+    public static policy.Policy.PolicyRuleEvent parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleAction parseFrom(byte[] data)
+    public static policy.Policy.PolicyRuleEvent parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRuleAction parseFrom(
+    public static policy.Policy.PolicyRuleEvent parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleAction parseFrom(java.io.InputStream input)
+    public static policy.Policy.PolicyRuleEvent parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRuleAction parseFrom(
+    public static policy.Policy.PolicyRuleEvent parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleAction parseDelimitedFrom(java.io.InputStream input)
+    public static policy.Policy.PolicyRuleEvent parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRuleAction parseDelimitedFrom(
+    public static policy.Policy.PolicyRuleEvent parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleAction parseFrom(
+    public static policy.Policy.PolicyRuleEvent parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRuleAction parseFrom(
+    public static policy.Policy.PolicyRuleEvent parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -4583,7 +1914,7 @@ public final class Policy {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(policy.Policy.PolicyRuleAction prototype) {
+    public static Builder newBuilder(policy.Policy.PolicyRuleEvent prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -4600,29 +1931,31 @@ public final class Policy {
     }
     /**
      * <pre>
-     * Action
+     * IETF draft: Framework for Use of ECA (Event Condition Action) in Network Self Management
+     *     Source: https://datatracker.ietf.org/doc/draft-bwd-netmod-eca-framework/
+     * Event
      * </pre>
      *
-     * Protobuf type {@code policy.PolicyRuleAction}
+     * Protobuf type {@code policy.PolicyRuleEvent}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleAction)
-        policy.Policy.PolicyRuleActionOrBuilder {
+        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleEvent)
+        policy.Policy.PolicyRuleEventOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return policy.Policy.internal_static_policy_PolicyRuleAction_descriptor;
+        return policy.Policy.internal_static_policy_PolicyRuleEvent_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return policy.Policy.internal_static_policy_PolicyRuleAction_fieldAccessorTable
+        return policy.Policy.internal_static_policy_PolicyRuleEvent_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                policy.Policy.PolicyRuleAction.class, policy.Policy.PolicyRuleAction.Builder.class);
+                policy.Policy.PolicyRuleEvent.class, policy.Policy.PolicyRuleEvent.Builder.class);
       }
 
-      // Construct using policy.Policy.PolicyRuleAction.newBuilder()
+      // Construct using policy.Policy.PolicyRuleEvent.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -4640,17 +1973,11 @@ public final class Policy {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (polRuleActionVarBuilder_ == null) {
-          polRuleActionVar_ = null;
-        } else {
-          polRuleActionVar_ = null;
-          polRuleActionVarBuilder_ = null;
-        }
-        if (polRuleActionValBuilder_ == null) {
-          polRuleActionVal_ = null;
+        if (eventBuilder_ == null) {
+          event_ = null;
         } else {
-          polRuleActionVal_ = null;
-          polRuleActionValBuilder_ = null;
+          event_ = null;
+          eventBuilder_ = null;
         }
         return this;
       }
@@ -4658,17 +1985,17 @@ public final class Policy {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return policy.Policy.internal_static_policy_PolicyRuleAction_descriptor;
+        return policy.Policy.internal_static_policy_PolicyRuleEvent_descriptor;
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRuleAction getDefaultInstanceForType() {
-        return policy.Policy.PolicyRuleAction.getDefaultInstance();
+      public policy.Policy.PolicyRuleEvent getDefaultInstanceForType() {
+        return policy.Policy.PolicyRuleEvent.getDefaultInstance();
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRuleAction build() {
-        policy.Policy.PolicyRuleAction result = buildPartial();
+      public policy.Policy.PolicyRuleEvent build() {
+        policy.Policy.PolicyRuleEvent result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -4676,17 +2003,12 @@ public final class Policy {
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRuleAction buildPartial() {
-        policy.Policy.PolicyRuleAction result = new policy.Policy.PolicyRuleAction(this);
-        if (polRuleActionVarBuilder_ == null) {
-          result.polRuleActionVar_ = polRuleActionVar_;
-        } else {
-          result.polRuleActionVar_ = polRuleActionVarBuilder_.build();
-        }
-        if (polRuleActionValBuilder_ == null) {
-          result.polRuleActionVal_ = polRuleActionVal_;
+      public policy.Policy.PolicyRuleEvent buildPartial() {
+        policy.Policy.PolicyRuleEvent result = new policy.Policy.PolicyRuleEvent(this);
+        if (eventBuilder_ == null) {
+          result.event_ = event_;
         } else {
-          result.polRuleActionVal_ = polRuleActionValBuilder_.build();
+          result.event_ = eventBuilder_.build();
         }
         onBuilt();
         return result;
@@ -4726,21 +2048,18 @@ public final class Policy {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof policy.Policy.PolicyRuleAction) {
-          return mergeFrom((policy.Policy.PolicyRuleAction)other);
+        if (other instanceof policy.Policy.PolicyRuleEvent) {
+          return mergeFrom((policy.Policy.PolicyRuleEvent)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(policy.Policy.PolicyRuleAction other) {
-        if (other == policy.Policy.PolicyRuleAction.getDefaultInstance()) return this;
-        if (other.hasPolRuleActionVar()) {
-          mergePolRuleActionVar(other.getPolRuleActionVar());
-        }
-        if (other.hasPolRuleActionVal()) {
-          mergePolRuleActionVal(other.getPolRuleActionVal());
+      public Builder mergeFrom(policy.Policy.PolicyRuleEvent other) {
+        if (other == policy.Policy.PolicyRuleEvent.getDefaultInstance()) return this;
+        if (other.hasEvent()) {
+          mergeEvent(other.getEvent());
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -4757,11 +2076,11 @@ public final class Policy {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        policy.Policy.PolicyRuleAction parsedMessage = null;
+        policy.Policy.PolicyRuleEvent parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (policy.Policy.PolicyRuleAction) e.getUnfinishedMessage();
+          parsedMessage = (policy.Policy.PolicyRuleEvent) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -4771,242 +2090,123 @@ public final class Policy {
         return this;
       }
 
-      private policy.Policy.PolicyRuleVariable polRuleActionVar_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleVariable, policy.Policy.PolicyRuleVariable.Builder, policy.Policy.PolicyRuleVariableOrBuilder> polRuleActionVarBuilder_;
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-       * @return Whether the polRuleActionVar field is set.
-       */
-      public boolean hasPolRuleActionVar() {
-        return polRuleActionVarBuilder_ != null || polRuleActionVar_ != null;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-       * @return The polRuleActionVar.
-       */
-      public policy.Policy.PolicyRuleVariable getPolRuleActionVar() {
-        if (polRuleActionVarBuilder_ == null) {
-          return polRuleActionVar_ == null ? policy.Policy.PolicyRuleVariable.getDefaultInstance() : polRuleActionVar_;
-        } else {
-          return polRuleActionVarBuilder_.getMessage();
-        }
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-       */
-      public Builder setPolRuleActionVar(policy.Policy.PolicyRuleVariable value) {
-        if (polRuleActionVarBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          polRuleActionVar_ = value;
-          onChanged();
-        } else {
-          polRuleActionVarBuilder_.setMessage(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-       */
-      public Builder setPolRuleActionVar(
-          policy.Policy.PolicyRuleVariable.Builder builderForValue) {
-        if (polRuleActionVarBuilder_ == null) {
-          polRuleActionVar_ = builderForValue.build();
-          onChanged();
-        } else {
-          polRuleActionVarBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-       */
-      public Builder mergePolRuleActionVar(policy.Policy.PolicyRuleVariable value) {
-        if (polRuleActionVarBuilder_ == null) {
-          if (polRuleActionVar_ != null) {
-            polRuleActionVar_ =
-              policy.Policy.PolicyRuleVariable.newBuilder(polRuleActionVar_).mergeFrom(value).buildPartial();
-          } else {
-            polRuleActionVar_ = value;
-          }
-          onChanged();
-        } else {
-          polRuleActionVarBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-       */
-      public Builder clearPolRuleActionVar() {
-        if (polRuleActionVarBuilder_ == null) {
-          polRuleActionVar_ = null;
-          onChanged();
-        } else {
-          polRuleActionVar_ = null;
-          polRuleActionVarBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-       */
-      public policy.Policy.PolicyRuleVariable.Builder getPolRuleActionVarBuilder() {
-        
-        onChanged();
-        return getPolRuleActionVarFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-       */
-      public policy.Policy.PolicyRuleVariableOrBuilder getPolRuleActionVarOrBuilder() {
-        if (polRuleActionVarBuilder_ != null) {
-          return polRuleActionVarBuilder_.getMessageOrBuilder();
-        } else {
-          return polRuleActionVar_ == null ?
-              policy.Policy.PolicyRuleVariable.getDefaultInstance() : polRuleActionVar_;
-        }
-      }
-      /**
-       * <code>.policy.PolicyRuleVariable polRuleActionVar = 1;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleVariable, policy.Policy.PolicyRuleVariable.Builder, policy.Policy.PolicyRuleVariableOrBuilder> 
-          getPolRuleActionVarFieldBuilder() {
-        if (polRuleActionVarBuilder_ == null) {
-          polRuleActionVarBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              policy.Policy.PolicyRuleVariable, policy.Policy.PolicyRuleVariable.Builder, policy.Policy.PolicyRuleVariableOrBuilder>(
-                  getPolRuleActionVar(),
-                  getParentForChildren(),
-                  isClean());
-          polRuleActionVar_ = null;
-        }
-        return polRuleActionVarBuilder_;
-      }
-
-      private policy.Policy.PolicyRuleValue polRuleActionVal_;
+      private context.ContextOuterClass.Event event_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleValue, policy.Policy.PolicyRuleValue.Builder, policy.Policy.PolicyRuleValueOrBuilder> polRuleActionValBuilder_;
+          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> eventBuilder_;
       /**
-       * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
-       * @return Whether the polRuleActionVal field is set.
+       * <code>.context.Event event = 1;</code>
+       * @return Whether the event field is set.
        */
-      public boolean hasPolRuleActionVal() {
-        return polRuleActionValBuilder_ != null || polRuleActionVal_ != null;
+      public boolean hasEvent() {
+        return eventBuilder_ != null || event_ != null;
       }
       /**
-       * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
-       * @return The polRuleActionVal.
+       * <code>.context.Event event = 1;</code>
+       * @return The event.
        */
-      public policy.Policy.PolicyRuleValue getPolRuleActionVal() {
-        if (polRuleActionValBuilder_ == null) {
-          return polRuleActionVal_ == null ? policy.Policy.PolicyRuleValue.getDefaultInstance() : polRuleActionVal_;
+      public context.ContextOuterClass.Event getEvent() {
+        if (eventBuilder_ == null) {
+          return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
         } else {
-          return polRuleActionValBuilder_.getMessage();
+          return eventBuilder_.getMessage();
         }
       }
       /**
-       * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
+       * <code>.context.Event event = 1;</code>
        */
-      public Builder setPolRuleActionVal(policy.Policy.PolicyRuleValue value) {
-        if (polRuleActionValBuilder_ == null) {
+      public Builder setEvent(context.ContextOuterClass.Event value) {
+        if (eventBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          polRuleActionVal_ = value;
+          event_ = value;
           onChanged();
         } else {
-          polRuleActionValBuilder_.setMessage(value);
+          eventBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
+       * <code>.context.Event event = 1;</code>
        */
-      public Builder setPolRuleActionVal(
-          policy.Policy.PolicyRuleValue.Builder builderForValue) {
-        if (polRuleActionValBuilder_ == null) {
-          polRuleActionVal_ = builderForValue.build();
+      public Builder setEvent(
+          context.ContextOuterClass.Event.Builder builderForValue) {
+        if (eventBuilder_ == null) {
+          event_ = builderForValue.build();
           onChanged();
         } else {
-          polRuleActionValBuilder_.setMessage(builderForValue.build());
+          eventBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
+       * <code>.context.Event event = 1;</code>
        */
-      public Builder mergePolRuleActionVal(policy.Policy.PolicyRuleValue value) {
-        if (polRuleActionValBuilder_ == null) {
-          if (polRuleActionVal_ != null) {
-            polRuleActionVal_ =
-              policy.Policy.PolicyRuleValue.newBuilder(polRuleActionVal_).mergeFrom(value).buildPartial();
+      public Builder mergeEvent(context.ContextOuterClass.Event value) {
+        if (eventBuilder_ == null) {
+          if (event_ != null) {
+            event_ =
+              context.ContextOuterClass.Event.newBuilder(event_).mergeFrom(value).buildPartial();
           } else {
-            polRuleActionVal_ = value;
+            event_ = value;
           }
           onChanged();
         } else {
-          polRuleActionValBuilder_.mergeFrom(value);
+          eventBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
+       * <code>.context.Event event = 1;</code>
        */
-      public Builder clearPolRuleActionVal() {
-        if (polRuleActionValBuilder_ == null) {
-          polRuleActionVal_ = null;
+      public Builder clearEvent() {
+        if (eventBuilder_ == null) {
+          event_ = null;
           onChanged();
         } else {
-          polRuleActionVal_ = null;
-          polRuleActionValBuilder_ = null;
+          event_ = null;
+          eventBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
+       * <code>.context.Event event = 1;</code>
        */
-      public policy.Policy.PolicyRuleValue.Builder getPolRuleActionValBuilder() {
+      public context.ContextOuterClass.Event.Builder getEventBuilder() {
         
         onChanged();
-        return getPolRuleActionValFieldBuilder().getBuilder();
+        return getEventFieldBuilder().getBuilder();
       }
       /**
-       * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
+       * <code>.context.Event event = 1;</code>
        */
-      public policy.Policy.PolicyRuleValueOrBuilder getPolRuleActionValOrBuilder() {
-        if (polRuleActionValBuilder_ != null) {
-          return polRuleActionValBuilder_.getMessageOrBuilder();
+      public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
+        if (eventBuilder_ != null) {
+          return eventBuilder_.getMessageOrBuilder();
         } else {
-          return polRuleActionVal_ == null ?
-              policy.Policy.PolicyRuleValue.getDefaultInstance() : polRuleActionVal_;
+          return event_ == null ?
+              context.ContextOuterClass.Event.getDefaultInstance() : event_;
         }
       }
       /**
-       * <code>.policy.PolicyRuleValue polRuleActionVal = 2;</code>
+       * <code>.context.Event event = 1;</code>
        */
       private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleValue, policy.Policy.PolicyRuleValue.Builder, policy.Policy.PolicyRuleValueOrBuilder> 
-          getPolRuleActionValFieldBuilder() {
-        if (polRuleActionValBuilder_ == null) {
-          polRuleActionValBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              policy.Policy.PolicyRuleValue, policy.Policy.PolicyRuleValue.Builder, policy.Policy.PolicyRuleValueOrBuilder>(
-                  getPolRuleActionVal(),
+          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> 
+          getEventFieldBuilder() {
+        if (eventBuilder_ == null) {
+          eventBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder>(
+                  getEvent(),
                   getParentForChildren(),
                   isClean());
-          polRuleActionVal_ = null;
+          event_ = null;
         }
-        return polRuleActionValBuilder_;
+        return eventBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -5021,41 +2221,41 @@ public final class Policy {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleAction)
+      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleEvent)
     }
 
-    // @@protoc_insertion_point(class_scope:policy.PolicyRuleAction)
-    private static final policy.Policy.PolicyRuleAction DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:policy.PolicyRuleEvent)
+    private static final policy.Policy.PolicyRuleEvent DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleAction();
+      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleEvent();
     }
 
-    public static policy.Policy.PolicyRuleAction getDefaultInstance() {
+    public static policy.Policy.PolicyRuleEvent getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<PolicyRuleAction>
-        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleAction>() {
+    private static final com.google.protobuf.Parser<PolicyRuleEvent>
+        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleEvent>() {
       @java.lang.Override
-      public PolicyRuleAction parsePartialFrom(
+      public PolicyRuleEvent parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new PolicyRuleAction(input, extensionRegistry);
+        return new PolicyRuleEvent(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<PolicyRuleAction> parser() {
+    public static com.google.protobuf.Parser<PolicyRuleEvent> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<PolicyRuleAction> getParserForType() {
+    public com.google.protobuf.Parser<PolicyRuleEvent> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public policy.Policy.PolicyRuleAction getDefaultInstanceForType() {
+    public policy.Policy.PolicyRuleEvent getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
@@ -5104,10 +2304,10 @@ public final class Policy {
     policy.Policy.PolicyRuleType getPolicyRuleType();
 
     /**
-     * <code>uint32 PolicyRulePriority = 3;</code>
-     * @return The policyRulePriority.
+     * <code>uint32 priority = 3;</code>
+     * @return The priority.
      */
-    int getPolicyRulePriority();
+    int getPriority();
 
     /**
      * <pre>
@@ -5141,153 +2341,155 @@ public final class Policy {
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
-    java.util.List<policy.Policy.PolicyRuleCondition> 
-        getPolRuleConditionListList();
+    java.util.List<policy.PolicyCondition.PolicyRuleCondition> 
+        getConditionListList();
     /**
      * <pre>
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
-    policy.Policy.PolicyRuleCondition getPolRuleConditionList(int index);
+    policy.PolicyCondition.PolicyRuleCondition getConditionList(int index);
     /**
      * <pre>
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
-    int getPolRuleConditionListCount();
+    int getConditionListCount();
     /**
      * <pre>
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
-    java.util.List<? extends policy.Policy.PolicyRuleConditionOrBuilder> 
-        getPolRuleConditionListOrBuilderList();
+    java.util.List<? extends policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
+        getConditionListOrBuilderList();
     /**
      * <pre>
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
-    policy.Policy.PolicyRuleConditionOrBuilder getPolRuleConditionListOrBuilder(
+    policy.PolicyCondition.PolicyRuleConditionOrBuilder getConditionListOrBuilder(
         int index);
 
     /**
      * <pre>
-     * One or more actions should be applied
+     * Evaluation operator to be used
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>.policy.BooleanOperator booleanOperator = 6;</code>
+     * @return The enum numeric value on the wire for booleanOperator.
      */
-    java.util.List<policy.Policy.PolicyRuleAction> 
-        getPolRuleActionListList();
+    int getBooleanOperatorValue();
     /**
      * <pre>
-     * One or more actions should be applied
+     * Evaluation operator to be used
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>.policy.BooleanOperator booleanOperator = 6;</code>
+     * @return The booleanOperator.
      */
-    policy.Policy.PolicyRuleAction getPolRuleActionList(int index);
+    policy.PolicyCondition.BooleanOperator getBooleanOperator();
+
     /**
      * <pre>
      * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
-    int getPolRuleActionListCount();
+    java.util.List<policy.PolicyAction.PolicyRuleAction> 
+        getActionListList();
     /**
      * <pre>
      * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
-    java.util.List<? extends policy.Policy.PolicyRuleActionOrBuilder> 
-        getPolRuleActionListOrBuilderList();
+    policy.PolicyAction.PolicyRuleAction getActionList(int index);
     /**
      * <pre>
      * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
-    policy.Policy.PolicyRuleActionOrBuilder getPolRuleActionListOrBuilder(
-        int index);
-
+    int getActionListCount();
     /**
      * <pre>
-     * Affected services and devices
+     * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
-    java.util.List<context.ContextOuterClass.ServiceId> 
-        getServiceListList();
+    java.util.List<? extends policy.PolicyAction.PolicyRuleActionOrBuilder> 
+        getActionListOrBuilderList();
     /**
      * <pre>
-     * Affected services and devices
+     * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
-    context.ContextOuterClass.ServiceId getServiceList(int index);
+    policy.PolicyAction.PolicyRuleActionOrBuilder getActionListOrBuilder(
+        int index);
+
     /**
      * <pre>
-     * Affected services and devices
+     * Affected service and devices
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>.context.ServiceId serviceId = 8;</code>
+     * @return Whether the serviceId field is set.
      */
-    int getServiceListCount();
+    boolean hasServiceId();
     /**
      * <pre>
-     * Affected services and devices
+     * Affected service and devices
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>.context.ServiceId serviceId = 8;</code>
+     * @return The serviceId.
      */
-    java.util.List<? extends context.ContextOuterClass.ServiceIdOrBuilder> 
-        getServiceListOrBuilderList();
+    context.ContextOuterClass.ServiceId getServiceId();
     /**
      * <pre>
-     * Affected services and devices
+     * Affected service and devices
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>.context.ServiceId serviceId = 8;</code>
      */
-    context.ContextOuterClass.ServiceIdOrBuilder getServiceListOrBuilder(
-        int index);
+    context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
 
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     java.util.List<context.ContextOuterClass.DeviceId> 
         getDeviceListList();
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     context.ContextOuterClass.DeviceId getDeviceList(int index);
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     int getDeviceListCount();
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
         getDeviceListOrBuilderList();
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
         int index);
@@ -5313,9 +2515,9 @@ public final class Policy {
     }
     private PolicyRule() {
       policyRuleType_ = 0;
-      polRuleConditionList_ = java.util.Collections.emptyList();
-      polRuleActionList_ = java.util.Collections.emptyList();
-      serviceList_ = java.util.Collections.emptyList();
+      conditionList_ = java.util.Collections.emptyList();
+      booleanOperator_ = 0;
+      actionList_ = java.util.Collections.emptyList();
       deviceList_ = java.util.Collections.emptyList();
     }
 
@@ -5371,7 +2573,7 @@ public final class Policy {
             }
             case 24: {
 
-              policyRulePriority_ = input.readUInt32();
+              priority_ = input.readUInt32();
               break;
             }
             case 34: {
@@ -5389,35 +2591,45 @@ public final class Policy {
             }
             case 42: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                polRuleConditionList_ = new java.util.ArrayList<policy.Policy.PolicyRuleCondition>();
+                conditionList_ = new java.util.ArrayList<policy.PolicyCondition.PolicyRuleCondition>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              polRuleConditionList_.add(
-                  input.readMessage(policy.Policy.PolicyRuleCondition.parser(), extensionRegistry));
+              conditionList_.add(
+                  input.readMessage(policy.PolicyCondition.PolicyRuleCondition.parser(), extensionRegistry));
               break;
             }
-            case 50: {
+            case 48: {
+              int rawValue = input.readEnum();
+
+              booleanOperator_ = rawValue;
+              break;
+            }
+            case 58: {
               if (!((mutable_bitField0_ & 0x00000002) != 0)) {
-                polRuleActionList_ = new java.util.ArrayList<policy.Policy.PolicyRuleAction>();
+                actionList_ = new java.util.ArrayList<policy.PolicyAction.PolicyRuleAction>();
                 mutable_bitField0_ |= 0x00000002;
               }
-              polRuleActionList_.add(
-                  input.readMessage(policy.Policy.PolicyRuleAction.parser(), extensionRegistry));
+              actionList_.add(
+                  input.readMessage(policy.PolicyAction.PolicyRuleAction.parser(), extensionRegistry));
               break;
             }
-            case 58: {
-              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
-                serviceList_ = new java.util.ArrayList<context.ContextOuterClass.ServiceId>();
-                mutable_bitField0_ |= 0x00000004;
+            case 66: {
+              context.ContextOuterClass.ServiceId.Builder subBuilder = null;
+              if (serviceId_ != null) {
+                subBuilder = serviceId_.toBuilder();
+              }
+              serviceId_ = input.readMessage(context.ContextOuterClass.ServiceId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(serviceId_);
+                serviceId_ = subBuilder.buildPartial();
               }
-              serviceList_.add(
-                  input.readMessage(context.ContextOuterClass.ServiceId.parser(), extensionRegistry));
+
               break;
             }
-            case 66: {
-              if (!((mutable_bitField0_ & 0x00000008) != 0)) {
+            case 74: {
+              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
                 deviceList_ = new java.util.ArrayList<context.ContextOuterClass.DeviceId>();
-                mutable_bitField0_ |= 0x00000008;
+                mutable_bitField0_ |= 0x00000004;
               }
               deviceList_.add(
                   input.readMessage(context.ContextOuterClass.DeviceId.parser(), extensionRegistry));
@@ -5439,15 +2651,12 @@ public final class Policy {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          polRuleConditionList_ = java.util.Collections.unmodifiableList(polRuleConditionList_);
+          conditionList_ = java.util.Collections.unmodifiableList(conditionList_);
         }
         if (((mutable_bitField0_ & 0x00000002) != 0)) {
-          polRuleActionList_ = java.util.Collections.unmodifiableList(polRuleActionList_);
+          actionList_ = java.util.Collections.unmodifiableList(actionList_);
         }
         if (((mutable_bitField0_ & 0x00000004) != 0)) {
-          serviceList_ = java.util.Collections.unmodifiableList(serviceList_);
-        }
-        if (((mutable_bitField0_ & 0x00000008) != 0)) {
           deviceList_ = java.util.Collections.unmodifiableList(deviceList_);
         }
         this.unknownFields = unknownFields.build();
@@ -5524,15 +2733,15 @@ public final class Policy {
       return result == null ? policy.Policy.PolicyRuleType.UNRECOGNIZED : result;
     }
 
-    public static final int POLICYRULEPRIORITY_FIELD_NUMBER = 3;
-    private int policyRulePriority_;
+    public static final int PRIORITY_FIELD_NUMBER = 3;
+    private int priority_;
     /**
-     * <code>uint32 PolicyRulePriority = 3;</code>
-     * @return The policyRulePriority.
+     * <code>uint32 priority = 3;</code>
+     * @return The priority.
      */
     @java.lang.Override
-    public int getPolicyRulePriority() {
-      return policyRulePriority_;
+    public int getPriority() {
+      return priority_;
     }
 
     public static final int EVENT_FIELD_NUMBER = 4;
@@ -5573,197 +2782,202 @@ public final class Policy {
       return getEvent();
     }
 
-    public static final int POLRULECONDITIONLIST_FIELD_NUMBER = 5;
-    private java.util.List<policy.Policy.PolicyRuleCondition> polRuleConditionList_;
+    public static final int CONDITIONLIST_FIELD_NUMBER = 5;
+    private java.util.List<policy.PolicyCondition.PolicyRuleCondition> conditionList_;
     /**
      * <pre>
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
     @java.lang.Override
-    public java.util.List<policy.Policy.PolicyRuleCondition> getPolRuleConditionListList() {
-      return polRuleConditionList_;
+    public java.util.List<policy.PolicyCondition.PolicyRuleCondition> getConditionListList() {
+      return conditionList_;
     }
     /**
      * <pre>
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
     @java.lang.Override
-    public java.util.List<? extends policy.Policy.PolicyRuleConditionOrBuilder> 
-        getPolRuleConditionListOrBuilderList() {
-      return polRuleConditionList_;
+    public java.util.List<? extends policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
+        getConditionListOrBuilderList() {
+      return conditionList_;
     }
     /**
      * <pre>
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
     @java.lang.Override
-    public int getPolRuleConditionListCount() {
-      return polRuleConditionList_.size();
+    public int getConditionListCount() {
+      return conditionList_.size();
     }
     /**
      * <pre>
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
     @java.lang.Override
-    public policy.Policy.PolicyRuleCondition getPolRuleConditionList(int index) {
-      return polRuleConditionList_.get(index);
+    public policy.PolicyCondition.PolicyRuleCondition getConditionList(int index) {
+      return conditionList_.get(index);
     }
     /**
      * <pre>
      * One or more conditions must be met
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
      */
     @java.lang.Override
-    public policy.Policy.PolicyRuleConditionOrBuilder getPolRuleConditionListOrBuilder(
+    public policy.PolicyCondition.PolicyRuleConditionOrBuilder getConditionListOrBuilder(
         int index) {
-      return polRuleConditionList_.get(index);
+      return conditionList_.get(index);
     }
 
-    public static final int POLRULEACTIONLIST_FIELD_NUMBER = 6;
-    private java.util.List<policy.Policy.PolicyRuleAction> polRuleActionList_;
+    public static final int BOOLEANOPERATOR_FIELD_NUMBER = 6;
+    private int booleanOperator_;
     /**
      * <pre>
-     * One or more actions should be applied
+     * Evaluation operator to be used
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>.policy.BooleanOperator booleanOperator = 6;</code>
+     * @return The enum numeric value on the wire for booleanOperator.
      */
-    @java.lang.Override
-    public java.util.List<policy.Policy.PolicyRuleAction> getPolRuleActionListList() {
-      return polRuleActionList_;
+    @java.lang.Override public int getBooleanOperatorValue() {
+      return booleanOperator_;
     }
     /**
      * <pre>
-     * One or more actions should be applied
+     * Evaluation operator to be used
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>.policy.BooleanOperator booleanOperator = 6;</code>
+     * @return The booleanOperator.
      */
-    @java.lang.Override
-    public java.util.List<? extends policy.Policy.PolicyRuleActionOrBuilder> 
-        getPolRuleActionListOrBuilderList() {
-      return polRuleActionList_;
+    @java.lang.Override public policy.PolicyCondition.BooleanOperator getBooleanOperator() {
+      @SuppressWarnings("deprecation")
+      policy.PolicyCondition.BooleanOperator result = policy.PolicyCondition.BooleanOperator.valueOf(booleanOperator_);
+      return result == null ? policy.PolicyCondition.BooleanOperator.UNRECOGNIZED : result;
     }
+
+    public static final int ACTIONLIST_FIELD_NUMBER = 7;
+    private java.util.List<policy.PolicyAction.PolicyRuleAction> actionList_;
     /**
      * <pre>
      * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
     @java.lang.Override
-    public int getPolRuleActionListCount() {
-      return polRuleActionList_.size();
+    public java.util.List<policy.PolicyAction.PolicyRuleAction> getActionListList() {
+      return actionList_;
     }
     /**
      * <pre>
      * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
     @java.lang.Override
-    public policy.Policy.PolicyRuleAction getPolRuleActionList(int index) {
-      return polRuleActionList_.get(index);
+    public java.util.List<? extends policy.PolicyAction.PolicyRuleActionOrBuilder> 
+        getActionListOrBuilderList() {
+      return actionList_;
     }
     /**
      * <pre>
      * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
     @java.lang.Override
-    public policy.Policy.PolicyRuleActionOrBuilder getPolRuleActionListOrBuilder(
-        int index) {
-      return polRuleActionList_.get(index);
+    public int getActionListCount() {
+      return actionList_.size();
     }
-
-    public static final int SERVICELIST_FIELD_NUMBER = 7;
-    private java.util.List<context.ContextOuterClass.ServiceId> serviceList_;
     /**
      * <pre>
-     * Affected services and devices
+     * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
     @java.lang.Override
-    public java.util.List<context.ContextOuterClass.ServiceId> getServiceListList() {
-      return serviceList_;
+    public policy.PolicyAction.PolicyRuleAction getActionList(int index) {
+      return actionList_.get(index);
     }
     /**
      * <pre>
-     * Affected services and devices
+     * One or more actions should be applied
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
      */
     @java.lang.Override
-    public java.util.List<? extends context.ContextOuterClass.ServiceIdOrBuilder> 
-        getServiceListOrBuilderList() {
-      return serviceList_;
+    public policy.PolicyAction.PolicyRuleActionOrBuilder getActionListOrBuilder(
+        int index) {
+      return actionList_.get(index);
     }
+
+    public static final int SERVICEID_FIELD_NUMBER = 8;
+    private context.ContextOuterClass.ServiceId serviceId_;
     /**
      * <pre>
-     * Affected services and devices
+     * Affected service and devices
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>.context.ServiceId serviceId = 8;</code>
+     * @return Whether the serviceId field is set.
      */
     @java.lang.Override
-    public int getServiceListCount() {
-      return serviceList_.size();
+    public boolean hasServiceId() {
+      return serviceId_ != null;
     }
     /**
      * <pre>
-     * Affected services and devices
+     * Affected service and devices
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>.context.ServiceId serviceId = 8;</code>
+     * @return The serviceId.
      */
     @java.lang.Override
-    public context.ContextOuterClass.ServiceId getServiceList(int index) {
-      return serviceList_.get(index);
+    public context.ContextOuterClass.ServiceId getServiceId() {
+      return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
     }
     /**
      * <pre>
-     * Affected services and devices
+     * Affected service and devices
      * </pre>
      *
-     * <code>repeated .context.ServiceId serviceList = 7;</code>
+     * <code>.context.ServiceId serviceId = 8;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.ServiceIdOrBuilder getServiceListOrBuilder(
-        int index) {
-      return serviceList_.get(index);
+    public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
+      return getServiceId();
     }
 
-    public static final int DEVICELIST_FIELD_NUMBER = 8;
+    public static final int DEVICELIST_FIELD_NUMBER = 9;
     private java.util.List<context.ContextOuterClass.DeviceId> deviceList_;
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     @java.lang.Override
     public java.util.List<context.ContextOuterClass.DeviceId> getDeviceListList() {
       return deviceList_;
     }
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     @java.lang.Override
     public java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
@@ -5771,21 +2985,21 @@ public final class Policy {
       return deviceList_;
     }
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     @java.lang.Override
     public int getDeviceListCount() {
       return deviceList_.size();
     }
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.DeviceId getDeviceList(int index) {
       return deviceList_.get(index);
     }
     /**
-     * <code>repeated .context.DeviceId deviceList = 8;</code>
+     * <code>repeated .context.DeviceId deviceList = 9;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
@@ -5813,23 +3027,26 @@ public final class Policy {
       if (policyRuleType_ != policy.Policy.PolicyRuleType.POLICYTYPE_DEVICE.getNumber()) {
         output.writeEnum(2, policyRuleType_);
       }
-      if (policyRulePriority_ != 0) {
-        output.writeUInt32(3, policyRulePriority_);
+      if (priority_ != 0) {
+        output.writeUInt32(3, priority_);
       }
       if (event_ != null) {
         output.writeMessage(4, getEvent());
       }
-      for (int i = 0; i < polRuleConditionList_.size(); i++) {
-        output.writeMessage(5, polRuleConditionList_.get(i));
+      for (int i = 0; i < conditionList_.size(); i++) {
+        output.writeMessage(5, conditionList_.get(i));
+      }
+      if (booleanOperator_ != policy.PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED.getNumber()) {
+        output.writeEnum(6, booleanOperator_);
       }
-      for (int i = 0; i < polRuleActionList_.size(); i++) {
-        output.writeMessage(6, polRuleActionList_.get(i));
+      for (int i = 0; i < actionList_.size(); i++) {
+        output.writeMessage(7, actionList_.get(i));
       }
-      for (int i = 0; i < serviceList_.size(); i++) {
-        output.writeMessage(7, serviceList_.get(i));
+      if (serviceId_ != null) {
+        output.writeMessage(8, getServiceId());
       }
       for (int i = 0; i < deviceList_.size(); i++) {
-        output.writeMessage(8, deviceList_.get(i));
+        output.writeMessage(9, deviceList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -5848,29 +3065,33 @@ public final class Policy {
         size += com.google.protobuf.CodedOutputStream
           .computeEnumSize(2, policyRuleType_);
       }
-      if (policyRulePriority_ != 0) {
+      if (priority_ != 0) {
         size += com.google.protobuf.CodedOutputStream
-          .computeUInt32Size(3, policyRulePriority_);
+          .computeUInt32Size(3, priority_);
       }
       if (event_ != null) {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(4, getEvent());
       }
-      for (int i = 0; i < polRuleConditionList_.size(); i++) {
+      for (int i = 0; i < conditionList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(5, conditionList_.get(i));
+      }
+      if (booleanOperator_ != policy.PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED.getNumber()) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, polRuleConditionList_.get(i));
+          .computeEnumSize(6, booleanOperator_);
       }
-      for (int i = 0; i < polRuleActionList_.size(); i++) {
+      for (int i = 0; i < actionList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(6, polRuleActionList_.get(i));
+          .computeMessageSize(7, actionList_.get(i));
       }
-      for (int i = 0; i < serviceList_.size(); i++) {
+      if (serviceId_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(7, serviceList_.get(i));
+          .computeMessageSize(8, getServiceId());
       }
       for (int i = 0; i < deviceList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(8, deviceList_.get(i));
+          .computeMessageSize(9, deviceList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -5893,19 +3114,23 @@ public final class Policy {
             .equals(other.getPolicyRuleId())) return false;
       }
       if (policyRuleType_ != other.policyRuleType_) return false;
-      if (getPolicyRulePriority()
-          != other.getPolicyRulePriority()) return false;
+      if (getPriority()
+          != other.getPriority()) return false;
       if (hasEvent() != other.hasEvent()) return false;
       if (hasEvent()) {
         if (!getEvent()
             .equals(other.getEvent())) return false;
       }
-      if (!getPolRuleConditionListList()
-          .equals(other.getPolRuleConditionListList())) return false;
-      if (!getPolRuleActionListList()
-          .equals(other.getPolRuleActionListList())) return false;
-      if (!getServiceListList()
-          .equals(other.getServiceListList())) return false;
+      if (!getConditionListList()
+          .equals(other.getConditionListList())) return false;
+      if (booleanOperator_ != other.booleanOperator_) return false;
+      if (!getActionListList()
+          .equals(other.getActionListList())) return false;
+      if (hasServiceId() != other.hasServiceId()) return false;
+      if (hasServiceId()) {
+        if (!getServiceId()
+            .equals(other.getServiceId())) return false;
+      }
       if (!getDeviceListList()
           .equals(other.getDeviceListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
@@ -5925,23 +3150,25 @@ public final class Policy {
       }
       hash = (37 * hash) + POLICYRULETYPE_FIELD_NUMBER;
       hash = (53 * hash) + policyRuleType_;
-      hash = (37 * hash) + POLICYRULEPRIORITY_FIELD_NUMBER;
-      hash = (53 * hash) + getPolicyRulePriority();
+      hash = (37 * hash) + PRIORITY_FIELD_NUMBER;
+      hash = (53 * hash) + getPriority();
       if (hasEvent()) {
         hash = (37 * hash) + EVENT_FIELD_NUMBER;
         hash = (53 * hash) + getEvent().hashCode();
       }
-      if (getPolRuleConditionListCount() > 0) {
-        hash = (37 * hash) + POLRULECONDITIONLIST_FIELD_NUMBER;
-        hash = (53 * hash) + getPolRuleConditionListList().hashCode();
+      if (getConditionListCount() > 0) {
+        hash = (37 * hash) + CONDITIONLIST_FIELD_NUMBER;
+        hash = (53 * hash) + getConditionListList().hashCode();
       }
-      if (getPolRuleActionListCount() > 0) {
-        hash = (37 * hash) + POLRULEACTIONLIST_FIELD_NUMBER;
-        hash = (53 * hash) + getPolRuleActionListList().hashCode();
+      hash = (37 * hash) + BOOLEANOPERATOR_FIELD_NUMBER;
+      hash = (53 * hash) + booleanOperator_;
+      if (getActionListCount() > 0) {
+        hash = (37 * hash) + ACTIONLIST_FIELD_NUMBER;
+        hash = (53 * hash) + getActionListList().hashCode();
       }
-      if (getServiceListCount() > 0) {
-        hash = (37 * hash) + SERVICELIST_FIELD_NUMBER;
-        hash = (53 * hash) + getServiceListList().hashCode();
+      if (hasServiceId()) {
+        hash = (37 * hash) + SERVICEID_FIELD_NUMBER;
+        hash = (53 * hash) + getServiceId().hashCode();
       }
       if (getDeviceListCount() > 0) {
         hash = (37 * hash) + DEVICELIST_FIELD_NUMBER;
@@ -6082,9 +3309,8 @@ public final class Policy {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getPolRuleConditionListFieldBuilder();
-          getPolRuleActionListFieldBuilder();
-          getServiceListFieldBuilder();
+          getConditionListFieldBuilder();
+          getActionListFieldBuilder();
           getDeviceListFieldBuilder();
         }
       }
@@ -6099,7 +3325,7 @@ public final class Policy {
         }
         policyRuleType_ = 0;
 
-        policyRulePriority_ = 0;
+        priority_ = 0;
 
         if (eventBuilder_ == null) {
           event_ = null;
@@ -6107,27 +3333,29 @@ public final class Policy {
           event_ = null;
           eventBuilder_ = null;
         }
-        if (polRuleConditionListBuilder_ == null) {
-          polRuleConditionList_ = java.util.Collections.emptyList();
+        if (conditionListBuilder_ == null) {
+          conditionList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
         } else {
-          polRuleConditionListBuilder_.clear();
+          conditionListBuilder_.clear();
         }
-        if (polRuleActionListBuilder_ == null) {
-          polRuleActionList_ = java.util.Collections.emptyList();
+        booleanOperator_ = 0;
+
+        if (actionListBuilder_ == null) {
+          actionList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000002);
         } else {
-          polRuleActionListBuilder_.clear();
+          actionListBuilder_.clear();
         }
-        if (serviceListBuilder_ == null) {
-          serviceList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000004);
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = null;
         } else {
-          serviceListBuilder_.clear();
+          serviceId_ = null;
+          serviceIdBuilder_ = null;
         }
         if (deviceListBuilder_ == null) {
           deviceList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000008);
+          bitField0_ = (bitField0_ & ~0x00000004);
         } else {
           deviceListBuilder_.clear();
         }
@@ -6164,43 +3392,40 @@ public final class Policy {
           result.policyRuleId_ = policyRuleIdBuilder_.build();
         }
         result.policyRuleType_ = policyRuleType_;
-        result.policyRulePriority_ = policyRulePriority_;
+        result.priority_ = priority_;
         if (eventBuilder_ == null) {
           result.event_ = event_;
         } else {
           result.event_ = eventBuilder_.build();
         }
-        if (polRuleConditionListBuilder_ == null) {
+        if (conditionListBuilder_ == null) {
           if (((bitField0_ & 0x00000001) != 0)) {
-            polRuleConditionList_ = java.util.Collections.unmodifiableList(polRuleConditionList_);
+            conditionList_ = java.util.Collections.unmodifiableList(conditionList_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
-          result.polRuleConditionList_ = polRuleConditionList_;
+          result.conditionList_ = conditionList_;
         } else {
-          result.polRuleConditionList_ = polRuleConditionListBuilder_.build();
+          result.conditionList_ = conditionListBuilder_.build();
         }
-        if (polRuleActionListBuilder_ == null) {
+        result.booleanOperator_ = booleanOperator_;
+        if (actionListBuilder_ == null) {
           if (((bitField0_ & 0x00000002) != 0)) {
-            polRuleActionList_ = java.util.Collections.unmodifiableList(polRuleActionList_);
+            actionList_ = java.util.Collections.unmodifiableList(actionList_);
             bitField0_ = (bitField0_ & ~0x00000002);
           }
-          result.polRuleActionList_ = polRuleActionList_;
+          result.actionList_ = actionList_;
         } else {
-          result.polRuleActionList_ = polRuleActionListBuilder_.build();
+          result.actionList_ = actionListBuilder_.build();
         }
-        if (serviceListBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) != 0)) {
-            serviceList_ = java.util.Collections.unmodifiableList(serviceList_);
-            bitField0_ = (bitField0_ & ~0x00000004);
-          }
-          result.serviceList_ = serviceList_;
+        if (serviceIdBuilder_ == null) {
+          result.serviceId_ = serviceId_;
         } else {
-          result.serviceList_ = serviceListBuilder_.build();
+          result.serviceId_ = serviceIdBuilder_.build();
         }
         if (deviceListBuilder_ == null) {
-          if (((bitField0_ & 0x00000008) != 0)) {
+          if (((bitField0_ & 0x00000004) != 0)) {
             deviceList_ = java.util.Collections.unmodifiableList(deviceList_);
-            bitField0_ = (bitField0_ & ~0x00000008);
+            bitField0_ = (bitField0_ & ~0x00000004);
           }
           result.deviceList_ = deviceList_;
         } else {
@@ -6260,95 +3485,75 @@ public final class Policy {
         if (other.policyRuleType_ != 0) {
           setPolicyRuleTypeValue(other.getPolicyRuleTypeValue());
         }
-        if (other.getPolicyRulePriority() != 0) {
-          setPolicyRulePriority(other.getPolicyRulePriority());
+        if (other.getPriority() != 0) {
+          setPriority(other.getPriority());
         }
         if (other.hasEvent()) {
           mergeEvent(other.getEvent());
         }
-        if (polRuleConditionListBuilder_ == null) {
-          if (!other.polRuleConditionList_.isEmpty()) {
-            if (polRuleConditionList_.isEmpty()) {
-              polRuleConditionList_ = other.polRuleConditionList_;
+        if (conditionListBuilder_ == null) {
+          if (!other.conditionList_.isEmpty()) {
+            if (conditionList_.isEmpty()) {
+              conditionList_ = other.conditionList_;
               bitField0_ = (bitField0_ & ~0x00000001);
             } else {
-              ensurePolRuleConditionListIsMutable();
-              polRuleConditionList_.addAll(other.polRuleConditionList_);
+              ensureConditionListIsMutable();
+              conditionList_.addAll(other.conditionList_);
             }
             onChanged();
           }
         } else {
-          if (!other.polRuleConditionList_.isEmpty()) {
-            if (polRuleConditionListBuilder_.isEmpty()) {
-              polRuleConditionListBuilder_.dispose();
-              polRuleConditionListBuilder_ = null;
-              polRuleConditionList_ = other.polRuleConditionList_;
+          if (!other.conditionList_.isEmpty()) {
+            if (conditionListBuilder_.isEmpty()) {
+              conditionListBuilder_.dispose();
+              conditionListBuilder_ = null;
+              conditionList_ = other.conditionList_;
               bitField0_ = (bitField0_ & ~0x00000001);
-              polRuleConditionListBuilder_ = 
+              conditionListBuilder_ = 
                 com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getPolRuleConditionListFieldBuilder() : null;
+                   getConditionListFieldBuilder() : null;
             } else {
-              polRuleConditionListBuilder_.addAllMessages(other.polRuleConditionList_);
+              conditionListBuilder_.addAllMessages(other.conditionList_);
             }
           }
         }
-        if (polRuleActionListBuilder_ == null) {
-          if (!other.polRuleActionList_.isEmpty()) {
-            if (polRuleActionList_.isEmpty()) {
-              polRuleActionList_ = other.polRuleActionList_;
+        if (other.booleanOperator_ != 0) {
+          setBooleanOperatorValue(other.getBooleanOperatorValue());
+        }
+        if (actionListBuilder_ == null) {
+          if (!other.actionList_.isEmpty()) {
+            if (actionList_.isEmpty()) {
+              actionList_ = other.actionList_;
               bitField0_ = (bitField0_ & ~0x00000002);
             } else {
-              ensurePolRuleActionListIsMutable();
-              polRuleActionList_.addAll(other.polRuleActionList_);
+              ensureActionListIsMutable();
+              actionList_.addAll(other.actionList_);
             }
             onChanged();
           }
         } else {
-          if (!other.polRuleActionList_.isEmpty()) {
-            if (polRuleActionListBuilder_.isEmpty()) {
-              polRuleActionListBuilder_.dispose();
-              polRuleActionListBuilder_ = null;
-              polRuleActionList_ = other.polRuleActionList_;
+          if (!other.actionList_.isEmpty()) {
+            if (actionListBuilder_.isEmpty()) {
+              actionListBuilder_.dispose();
+              actionListBuilder_ = null;
+              actionList_ = other.actionList_;
               bitField0_ = (bitField0_ & ~0x00000002);
-              polRuleActionListBuilder_ = 
+              actionListBuilder_ = 
                 com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getPolRuleActionListFieldBuilder() : null;
+                   getActionListFieldBuilder() : null;
             } else {
-              polRuleActionListBuilder_.addAllMessages(other.polRuleActionList_);
+              actionListBuilder_.addAllMessages(other.actionList_);
             }
           }
         }
-        if (serviceListBuilder_ == null) {
-          if (!other.serviceList_.isEmpty()) {
-            if (serviceList_.isEmpty()) {
-              serviceList_ = other.serviceList_;
-              bitField0_ = (bitField0_ & ~0x00000004);
-            } else {
-              ensureServiceListIsMutable();
-              serviceList_.addAll(other.serviceList_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.serviceList_.isEmpty()) {
-            if (serviceListBuilder_.isEmpty()) {
-              serviceListBuilder_.dispose();
-              serviceListBuilder_ = null;
-              serviceList_ = other.serviceList_;
-              bitField0_ = (bitField0_ & ~0x00000004);
-              serviceListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getServiceListFieldBuilder() : null;
-            } else {
-              serviceListBuilder_.addAllMessages(other.serviceList_);
-            }
-          }
+        if (other.hasServiceId()) {
+          mergeServiceId(other.getServiceId());
         }
         if (deviceListBuilder_ == null) {
           if (!other.deviceList_.isEmpty()) {
             if (deviceList_.isEmpty()) {
               deviceList_ = other.deviceList_;
-              bitField0_ = (bitField0_ & ~0x00000008);
+              bitField0_ = (bitField0_ & ~0x00000004);
             } else {
               ensureDeviceListIsMutable();
               deviceList_.addAll(other.deviceList_);
@@ -6361,7 +3566,7 @@ public final class Policy {
               deviceListBuilder_.dispose();
               deviceListBuilder_ = null;
               deviceList_ = other.deviceList_;
-              bitField0_ = (bitField0_ & ~0x00000008);
+              bitField0_ = (bitField0_ & ~0x00000004);
               deviceListBuilder_ = 
                 com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                    getDeviceListFieldBuilder() : null;
@@ -6609,33 +3814,33 @@ public final class Policy {
         return this;
       }
 
-      private int policyRulePriority_ ;
+      private int priority_ ;
       /**
-       * <code>uint32 PolicyRulePriority = 3;</code>
-       * @return The policyRulePriority.
+       * <code>uint32 priority = 3;</code>
+       * @return The priority.
        */
       @java.lang.Override
-      public int getPolicyRulePriority() {
-        return policyRulePriority_;
+      public int getPriority() {
+        return priority_;
       }
       /**
-       * <code>uint32 PolicyRulePriority = 3;</code>
-       * @param value The policyRulePriority to set.
+       * <code>uint32 priority = 3;</code>
+       * @param value The priority to set.
        * @return This builder for chaining.
        */
-      public Builder setPolicyRulePriority(int value) {
+      public Builder setPriority(int value) {
         
-        policyRulePriority_ = value;
+        priority_ = value;
         onChanged();
         return this;
       }
       /**
-       * <code>uint32 PolicyRulePriority = 3;</code>
+       * <code>uint32 priority = 3;</code>
        * @return This builder for chaining.
        */
-      public Builder clearPolicyRulePriority() {
+      public Builder clearPriority() {
         
-        policyRulePriority_ = 0;
+        priority_ = 0;
         onChanged();
         return this;
       }
@@ -6795,30 +4000,30 @@ public final class Policy {
         return eventBuilder_;
       }
 
-      private java.util.List<policy.Policy.PolicyRuleCondition> polRuleConditionList_ =
+      private java.util.List<policy.PolicyCondition.PolicyRuleCondition> conditionList_ =
         java.util.Collections.emptyList();
-      private void ensurePolRuleConditionListIsMutable() {
+      private void ensureConditionListIsMutable() {
         if (!((bitField0_ & 0x00000001) != 0)) {
-          polRuleConditionList_ = new java.util.ArrayList<policy.Policy.PolicyRuleCondition>(polRuleConditionList_);
+          conditionList_ = new java.util.ArrayList<policy.PolicyCondition.PolicyRuleCondition>(conditionList_);
           bitField0_ |= 0x00000001;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.Policy.PolicyRuleCondition, policy.Policy.PolicyRuleCondition.Builder, policy.Policy.PolicyRuleConditionOrBuilder> polRuleConditionListBuilder_;
+          policy.PolicyCondition.PolicyRuleCondition, policy.PolicyCondition.PolicyRuleCondition.Builder, policy.PolicyCondition.PolicyRuleConditionOrBuilder> conditionListBuilder_;
 
       /**
        * <pre>
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public java.util.List<policy.Policy.PolicyRuleCondition> getPolRuleConditionListList() {
-        if (polRuleConditionListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(polRuleConditionList_);
+      public java.util.List<policy.PolicyCondition.PolicyRuleCondition> getConditionListList() {
+        if (conditionListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(conditionList_);
         } else {
-          return polRuleConditionListBuilder_.getMessageList();
+          return conditionListBuilder_.getMessageList();
         }
       }
       /**
@@ -6826,13 +4031,13 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public int getPolRuleConditionListCount() {
-        if (polRuleConditionListBuilder_ == null) {
-          return polRuleConditionList_.size();
+      public int getConditionListCount() {
+        if (conditionListBuilder_ == null) {
+          return conditionList_.size();
         } else {
-          return polRuleConditionListBuilder_.getCount();
+          return conditionListBuilder_.getCount();
         }
       }
       /**
@@ -6840,13 +4045,13 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public policy.Policy.PolicyRuleCondition getPolRuleConditionList(int index) {
-        if (polRuleConditionListBuilder_ == null) {
-          return polRuleConditionList_.get(index);
+      public policy.PolicyCondition.PolicyRuleCondition getConditionList(int index) {
+        if (conditionListBuilder_ == null) {
+          return conditionList_.get(index);
         } else {
-          return polRuleConditionListBuilder_.getMessage(index);
+          return conditionListBuilder_.getMessage(index);
         }
       }
       /**
@@ -6854,19 +4059,19 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public Builder setPolRuleConditionList(
-          int index, policy.Policy.PolicyRuleCondition value) {
-        if (polRuleConditionListBuilder_ == null) {
+      public Builder setConditionList(
+          int index, policy.PolicyCondition.PolicyRuleCondition value) {
+        if (conditionListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensurePolRuleConditionListIsMutable();
-          polRuleConditionList_.set(index, value);
+          ensureConditionListIsMutable();
+          conditionList_.set(index, value);
           onChanged();
         } else {
-          polRuleConditionListBuilder_.setMessage(index, value);
+          conditionListBuilder_.setMessage(index, value);
         }
         return this;
       }
@@ -6875,16 +4080,16 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public Builder setPolRuleConditionList(
-          int index, policy.Policy.PolicyRuleCondition.Builder builderForValue) {
-        if (polRuleConditionListBuilder_ == null) {
-          ensurePolRuleConditionListIsMutable();
-          polRuleConditionList_.set(index, builderForValue.build());
+      public Builder setConditionList(
+          int index, policy.PolicyCondition.PolicyRuleCondition.Builder builderForValue) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
+          conditionList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          polRuleConditionListBuilder_.setMessage(index, builderForValue.build());
+          conditionListBuilder_.setMessage(index, builderForValue.build());
         }
         return this;
       }
@@ -6893,18 +4098,18 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public Builder addPolRuleConditionList(policy.Policy.PolicyRuleCondition value) {
-        if (polRuleConditionListBuilder_ == null) {
+      public Builder addConditionList(policy.PolicyCondition.PolicyRuleCondition value) {
+        if (conditionListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensurePolRuleConditionListIsMutable();
-          polRuleConditionList_.add(value);
+          ensureConditionListIsMutable();
+          conditionList_.add(value);
           onChanged();
         } else {
-          polRuleConditionListBuilder_.addMessage(value);
+          conditionListBuilder_.addMessage(value);
         }
         return this;
       }
@@ -6913,19 +4118,19 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public Builder addPolRuleConditionList(
-          int index, policy.Policy.PolicyRuleCondition value) {
-        if (polRuleConditionListBuilder_ == null) {
+      public Builder addConditionList(
+          int index, policy.PolicyCondition.PolicyRuleCondition value) {
+        if (conditionListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensurePolRuleConditionListIsMutable();
-          polRuleConditionList_.add(index, value);
+          ensureConditionListIsMutable();
+          conditionList_.add(index, value);
           onChanged();
         } else {
-          polRuleConditionListBuilder_.addMessage(index, value);
+          conditionListBuilder_.addMessage(index, value);
         }
         return this;
       }
@@ -6934,16 +4139,16 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public Builder addPolRuleConditionList(
-          policy.Policy.PolicyRuleCondition.Builder builderForValue) {
-        if (polRuleConditionListBuilder_ == null) {
-          ensurePolRuleConditionListIsMutable();
-          polRuleConditionList_.add(builderForValue.build());
+      public Builder addConditionList(
+          policy.PolicyCondition.PolicyRuleCondition.Builder builderForValue) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
+          conditionList_.add(builderForValue.build());
           onChanged();
         } else {
-          polRuleConditionListBuilder_.addMessage(builderForValue.build());
+          conditionListBuilder_.addMessage(builderForValue.build());
         }
         return this;
       }
@@ -6952,16 +4157,16 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public Builder addPolRuleConditionList(
-          int index, policy.Policy.PolicyRuleCondition.Builder builderForValue) {
-        if (polRuleConditionListBuilder_ == null) {
-          ensurePolRuleConditionListIsMutable();
-          polRuleConditionList_.add(index, builderForValue.build());
+      public Builder addConditionList(
+          int index, policy.PolicyCondition.PolicyRuleCondition.Builder builderForValue) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
+          conditionList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          polRuleConditionListBuilder_.addMessage(index, builderForValue.build());
+          conditionListBuilder_.addMessage(index, builderForValue.build());
         }
         return this;
       }
@@ -6970,17 +4175,17 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public Builder addAllPolRuleConditionList(
-          java.lang.Iterable<? extends policy.Policy.PolicyRuleCondition> values) {
-        if (polRuleConditionListBuilder_ == null) {
-          ensurePolRuleConditionListIsMutable();
+      public Builder addAllConditionList(
+          java.lang.Iterable<? extends policy.PolicyCondition.PolicyRuleCondition> values) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, polRuleConditionList_);
+              values, conditionList_);
           onChanged();
         } else {
-          polRuleConditionListBuilder_.addAllMessages(values);
+          conditionListBuilder_.addAllMessages(values);
         }
         return this;
       }
@@ -6989,15 +4194,15 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public Builder clearPolRuleConditionList() {
-        if (polRuleConditionListBuilder_ == null) {
-          polRuleConditionList_ = java.util.Collections.emptyList();
+      public Builder clearConditionList() {
+        if (conditionListBuilder_ == null) {
+          conditionList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          polRuleConditionListBuilder_.clear();
+          conditionListBuilder_.clear();
         }
         return this;
       }
@@ -7006,15 +4211,15 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public Builder removePolRuleConditionList(int index) {
-        if (polRuleConditionListBuilder_ == null) {
-          ensurePolRuleConditionListIsMutable();
-          polRuleConditionList_.remove(index);
+      public Builder removeConditionList(int index) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
+          conditionList_.remove(index);
           onChanged();
         } else {
-          polRuleConditionListBuilder_.remove(index);
+          conditionListBuilder_.remove(index);
         }
         return this;
       }
@@ -7023,24 +4228,24 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public policy.Policy.PolicyRuleCondition.Builder getPolRuleConditionListBuilder(
+      public policy.PolicyCondition.PolicyRuleCondition.Builder getConditionListBuilder(
           int index) {
-        return getPolRuleConditionListFieldBuilder().getBuilder(index);
+        return getConditionListFieldBuilder().getBuilder(index);
       }
       /**
        * <pre>
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public policy.Policy.PolicyRuleConditionOrBuilder getPolRuleConditionListOrBuilder(
+      public policy.PolicyCondition.PolicyRuleConditionOrBuilder getConditionListOrBuilder(
           int index) {
-        if (polRuleConditionListBuilder_ == null) {
-          return polRuleConditionList_.get(index);  } else {
-          return polRuleConditionListBuilder_.getMessageOrBuilder(index);
+        if (conditionListBuilder_ == null) {
+          return conditionList_.get(index);  } else {
+          return conditionListBuilder_.getMessageOrBuilder(index);
         }
       }
       /**
@@ -7048,14 +4253,14 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public java.util.List<? extends policy.Policy.PolicyRuleConditionOrBuilder> 
-           getPolRuleConditionListOrBuilderList() {
-        if (polRuleConditionListBuilder_ != null) {
-          return polRuleConditionListBuilder_.getMessageOrBuilderList();
+      public java.util.List<? extends policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
+           getConditionListOrBuilderList() {
+        if (conditionListBuilder_ != null) {
+          return conditionListBuilder_.getMessageOrBuilderList();
         } else {
-          return java.util.Collections.unmodifiableList(polRuleConditionList_);
+          return java.util.Collections.unmodifiableList(conditionList_);
         }
       }
       /**
@@ -7063,74 +4268,148 @@ public final class Policy {
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public policy.Policy.PolicyRuleCondition.Builder addPolRuleConditionListBuilder() {
-        return getPolRuleConditionListFieldBuilder().addBuilder(
-            policy.Policy.PolicyRuleCondition.getDefaultInstance());
+      public policy.PolicyCondition.PolicyRuleCondition.Builder addConditionListBuilder() {
+        return getConditionListFieldBuilder().addBuilder(
+            policy.PolicyCondition.PolicyRuleCondition.getDefaultInstance());
       }
       /**
        * <pre>
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public policy.Policy.PolicyRuleCondition.Builder addPolRuleConditionListBuilder(
+      public policy.PolicyCondition.PolicyRuleCondition.Builder addConditionListBuilder(
           int index) {
-        return getPolRuleConditionListFieldBuilder().addBuilder(
-            index, policy.Policy.PolicyRuleCondition.getDefaultInstance());
+        return getConditionListFieldBuilder().addBuilder(
+            index, policy.PolicyCondition.PolicyRuleCondition.getDefaultInstance());
       }
       /**
        * <pre>
        * One or more conditions must be met
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleCondition polRuleConditionList = 5;</code>
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
        */
-      public java.util.List<policy.Policy.PolicyRuleCondition.Builder> 
-           getPolRuleConditionListBuilderList() {
-        return getPolRuleConditionListFieldBuilder().getBuilderList();
+      public java.util.List<policy.PolicyCondition.PolicyRuleCondition.Builder> 
+           getConditionListBuilderList() {
+        return getConditionListFieldBuilder().getBuilderList();
       }
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.Policy.PolicyRuleCondition, policy.Policy.PolicyRuleCondition.Builder, policy.Policy.PolicyRuleConditionOrBuilder> 
-          getPolRuleConditionListFieldBuilder() {
-        if (polRuleConditionListBuilder_ == null) {
-          polRuleConditionListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              policy.Policy.PolicyRuleCondition, policy.Policy.PolicyRuleCondition.Builder, policy.Policy.PolicyRuleConditionOrBuilder>(
-                  polRuleConditionList_,
+          policy.PolicyCondition.PolicyRuleCondition, policy.PolicyCondition.PolicyRuleCondition.Builder, policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
+          getConditionListFieldBuilder() {
+        if (conditionListBuilder_ == null) {
+          conditionListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              policy.PolicyCondition.PolicyRuleCondition, policy.PolicyCondition.PolicyRuleCondition.Builder, policy.PolicyCondition.PolicyRuleConditionOrBuilder>(
+                  conditionList_,
                   ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          polRuleConditionList_ = null;
+          conditionList_ = null;
+        }
+        return conditionListBuilder_;
+      }
+
+      private int booleanOperator_ = 0;
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
+       * @return The enum numeric value on the wire for booleanOperator.
+       */
+      @java.lang.Override public int getBooleanOperatorValue() {
+        return booleanOperator_;
+      }
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
+       * @param value The enum numeric value on the wire for booleanOperator to set.
+       * @return This builder for chaining.
+       */
+      public Builder setBooleanOperatorValue(int value) {
+        
+        booleanOperator_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
+       * @return The booleanOperator.
+       */
+      @java.lang.Override
+      public policy.PolicyCondition.BooleanOperator getBooleanOperator() {
+        @SuppressWarnings("deprecation")
+        policy.PolicyCondition.BooleanOperator result = policy.PolicyCondition.BooleanOperator.valueOf(booleanOperator_);
+        return result == null ? policy.PolicyCondition.BooleanOperator.UNRECOGNIZED : result;
+      }
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
+       * @param value The booleanOperator to set.
+       * @return This builder for chaining.
+       */
+      public Builder setBooleanOperator(policy.PolicyCondition.BooleanOperator value) {
+        if (value == null) {
+          throw new NullPointerException();
         }
-        return polRuleConditionListBuilder_;
+        
+        booleanOperator_ = value.getNumber();
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearBooleanOperator() {
+        
+        booleanOperator_ = 0;
+        onChanged();
+        return this;
       }
 
-      private java.util.List<policy.Policy.PolicyRuleAction> polRuleActionList_ =
+      private java.util.List<policy.PolicyAction.PolicyRuleAction> actionList_ =
         java.util.Collections.emptyList();
-      private void ensurePolRuleActionListIsMutable() {
+      private void ensureActionListIsMutable() {
         if (!((bitField0_ & 0x00000002) != 0)) {
-          polRuleActionList_ = new java.util.ArrayList<policy.Policy.PolicyRuleAction>(polRuleActionList_);
+          actionList_ = new java.util.ArrayList<policy.PolicyAction.PolicyRuleAction>(actionList_);
           bitField0_ |= 0x00000002;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.Policy.PolicyRuleAction, policy.Policy.PolicyRuleAction.Builder, policy.Policy.PolicyRuleActionOrBuilder> polRuleActionListBuilder_;
+          policy.PolicyAction.PolicyRuleAction, policy.PolicyAction.PolicyRuleAction.Builder, policy.PolicyAction.PolicyRuleActionOrBuilder> actionListBuilder_;
 
       /**
        * <pre>
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public java.util.List<policy.Policy.PolicyRuleAction> getPolRuleActionListList() {
-        if (polRuleActionListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(polRuleActionList_);
+      public java.util.List<policy.PolicyAction.PolicyRuleAction> getActionListList() {
+        if (actionListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(actionList_);
         } else {
-          return polRuleActionListBuilder_.getMessageList();
+          return actionListBuilder_.getMessageList();
         }
       }
       /**
@@ -7138,13 +4417,13 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public int getPolRuleActionListCount() {
-        if (polRuleActionListBuilder_ == null) {
-          return polRuleActionList_.size();
+      public int getActionListCount() {
+        if (actionListBuilder_ == null) {
+          return actionList_.size();
         } else {
-          return polRuleActionListBuilder_.getCount();
+          return actionListBuilder_.getCount();
         }
       }
       /**
@@ -7152,13 +4431,13 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public policy.Policy.PolicyRuleAction getPolRuleActionList(int index) {
-        if (polRuleActionListBuilder_ == null) {
-          return polRuleActionList_.get(index);
+      public policy.PolicyAction.PolicyRuleAction getActionList(int index) {
+        if (actionListBuilder_ == null) {
+          return actionList_.get(index);
         } else {
-          return polRuleActionListBuilder_.getMessage(index);
+          return actionListBuilder_.getMessage(index);
         }
       }
       /**
@@ -7166,19 +4445,19 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public Builder setPolRuleActionList(
-          int index, policy.Policy.PolicyRuleAction value) {
-        if (polRuleActionListBuilder_ == null) {
+      public Builder setActionList(
+          int index, policy.PolicyAction.PolicyRuleAction value) {
+        if (actionListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensurePolRuleActionListIsMutable();
-          polRuleActionList_.set(index, value);
+          ensureActionListIsMutable();
+          actionList_.set(index, value);
           onChanged();
         } else {
-          polRuleActionListBuilder_.setMessage(index, value);
+          actionListBuilder_.setMessage(index, value);
         }
         return this;
       }
@@ -7187,16 +4466,16 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public Builder setPolRuleActionList(
-          int index, policy.Policy.PolicyRuleAction.Builder builderForValue) {
-        if (polRuleActionListBuilder_ == null) {
-          ensurePolRuleActionListIsMutable();
-          polRuleActionList_.set(index, builderForValue.build());
+      public Builder setActionList(
+          int index, policy.PolicyAction.PolicyRuleAction.Builder builderForValue) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
+          actionList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          polRuleActionListBuilder_.setMessage(index, builderForValue.build());
+          actionListBuilder_.setMessage(index, builderForValue.build());
         }
         return this;
       }
@@ -7205,18 +4484,18 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public Builder addPolRuleActionList(policy.Policy.PolicyRuleAction value) {
-        if (polRuleActionListBuilder_ == null) {
+      public Builder addActionList(policy.PolicyAction.PolicyRuleAction value) {
+        if (actionListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensurePolRuleActionListIsMutable();
-          polRuleActionList_.add(value);
+          ensureActionListIsMutable();
+          actionList_.add(value);
           onChanged();
         } else {
-          polRuleActionListBuilder_.addMessage(value);
+          actionListBuilder_.addMessage(value);
         }
         return this;
       }
@@ -7225,19 +4504,19 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public Builder addPolRuleActionList(
-          int index, policy.Policy.PolicyRuleAction value) {
-        if (polRuleActionListBuilder_ == null) {
+      public Builder addActionList(
+          int index, policy.PolicyAction.PolicyRuleAction value) {
+        if (actionListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensurePolRuleActionListIsMutable();
-          polRuleActionList_.add(index, value);
+          ensureActionListIsMutable();
+          actionList_.add(index, value);
           onChanged();
         } else {
-          polRuleActionListBuilder_.addMessage(index, value);
+          actionListBuilder_.addMessage(index, value);
         }
         return this;
       }
@@ -7246,16 +4525,16 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public Builder addPolRuleActionList(
-          policy.Policy.PolicyRuleAction.Builder builderForValue) {
-        if (polRuleActionListBuilder_ == null) {
-          ensurePolRuleActionListIsMutable();
-          polRuleActionList_.add(builderForValue.build());
+      public Builder addActionList(
+          policy.PolicyAction.PolicyRuleAction.Builder builderForValue) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
+          actionList_.add(builderForValue.build());
           onChanged();
         } else {
-          polRuleActionListBuilder_.addMessage(builderForValue.build());
+          actionListBuilder_.addMessage(builderForValue.build());
         }
         return this;
       }
@@ -7264,16 +4543,16 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public Builder addPolRuleActionList(
-          int index, policy.Policy.PolicyRuleAction.Builder builderForValue) {
-        if (polRuleActionListBuilder_ == null) {
-          ensurePolRuleActionListIsMutable();
-          polRuleActionList_.add(index, builderForValue.build());
+      public Builder addActionList(
+          int index, policy.PolicyAction.PolicyRuleAction.Builder builderForValue) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
+          actionList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          polRuleActionListBuilder_.addMessage(index, builderForValue.build());
+          actionListBuilder_.addMessage(index, builderForValue.build());
         }
         return this;
       }
@@ -7282,17 +4561,17 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public Builder addAllPolRuleActionList(
-          java.lang.Iterable<? extends policy.Policy.PolicyRuleAction> values) {
-        if (polRuleActionListBuilder_ == null) {
-          ensurePolRuleActionListIsMutable();
+      public Builder addAllActionList(
+          java.lang.Iterable<? extends policy.PolicyAction.PolicyRuleAction> values) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, polRuleActionList_);
+              values, actionList_);
           onChanged();
         } else {
-          polRuleActionListBuilder_.addAllMessages(values);
+          actionListBuilder_.addAllMessages(values);
         }
         return this;
       }
@@ -7301,15 +4580,15 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public Builder clearPolRuleActionList() {
-        if (polRuleActionListBuilder_ == null) {
-          polRuleActionList_ = java.util.Collections.emptyList();
+      public Builder clearActionList() {
+        if (actionListBuilder_ == null) {
+          actionList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000002);
           onChanged();
         } else {
-          polRuleActionListBuilder_.clear();
+          actionListBuilder_.clear();
         }
         return this;
       }
@@ -7318,15 +4597,15 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public Builder removePolRuleActionList(int index) {
-        if (polRuleActionListBuilder_ == null) {
-          ensurePolRuleActionListIsMutable();
-          polRuleActionList_.remove(index);
+      public Builder removeActionList(int index) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
+          actionList_.remove(index);
           onChanged();
         } else {
-          polRuleActionListBuilder_.remove(index);
+          actionListBuilder_.remove(index);
         }
         return this;
       }
@@ -7335,24 +4614,24 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public policy.Policy.PolicyRuleAction.Builder getPolRuleActionListBuilder(
+      public policy.PolicyAction.PolicyRuleAction.Builder getActionListBuilder(
           int index) {
-        return getPolRuleActionListFieldBuilder().getBuilder(index);
+        return getActionListFieldBuilder().getBuilder(index);
       }
       /**
        * <pre>
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public policy.Policy.PolicyRuleActionOrBuilder getPolRuleActionListOrBuilder(
+      public policy.PolicyAction.PolicyRuleActionOrBuilder getActionListOrBuilder(
           int index) {
-        if (polRuleActionListBuilder_ == null) {
-          return polRuleActionList_.get(index);  } else {
-          return polRuleActionListBuilder_.getMessageOrBuilder(index);
+        if (actionListBuilder_ == null) {
+          return actionList_.get(index);  } else {
+          return actionListBuilder_.getMessageOrBuilder(index);
         }
       }
       /**
@@ -7360,14 +4639,14 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public java.util.List<? extends policy.Policy.PolicyRuleActionOrBuilder> 
-           getPolRuleActionListOrBuilderList() {
-        if (polRuleActionListBuilder_ != null) {
-          return polRuleActionListBuilder_.getMessageOrBuilderList();
+      public java.util.List<? extends policy.PolicyAction.PolicyRuleActionOrBuilder> 
+           getActionListOrBuilderList() {
+        if (actionListBuilder_ != null) {
+          return actionListBuilder_.getMessageOrBuilderList();
         } else {
-          return java.util.Collections.unmodifiableList(polRuleActionList_);
+          return java.util.Collections.unmodifiableList(actionList_);
         }
       }
       /**
@@ -7375,368 +4654,211 @@ public final class Policy {
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public policy.Policy.PolicyRuleAction.Builder addPolRuleActionListBuilder() {
-        return getPolRuleActionListFieldBuilder().addBuilder(
-            policy.Policy.PolicyRuleAction.getDefaultInstance());
+      public policy.PolicyAction.PolicyRuleAction.Builder addActionListBuilder() {
+        return getActionListFieldBuilder().addBuilder(
+            policy.PolicyAction.PolicyRuleAction.getDefaultInstance());
       }
       /**
        * <pre>
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public policy.Policy.PolicyRuleAction.Builder addPolRuleActionListBuilder(
+      public policy.PolicyAction.PolicyRuleAction.Builder addActionListBuilder(
           int index) {
-        return getPolRuleActionListFieldBuilder().addBuilder(
-            index, policy.Policy.PolicyRuleAction.getDefaultInstance());
+        return getActionListFieldBuilder().addBuilder(
+            index, policy.PolicyAction.PolicyRuleAction.getDefaultInstance());
       }
       /**
        * <pre>
        * One or more actions should be applied
        * </pre>
        *
-       * <code>repeated .policy.PolicyRuleAction polRuleActionList = 6;</code>
+       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
        */
-      public java.util.List<policy.Policy.PolicyRuleAction.Builder> 
-           getPolRuleActionListBuilderList() {
-        return getPolRuleActionListFieldBuilder().getBuilderList();
+      public java.util.List<policy.PolicyAction.PolicyRuleAction.Builder> 
+           getActionListBuilderList() {
+        return getActionListFieldBuilder().getBuilderList();
       }
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.Policy.PolicyRuleAction, policy.Policy.PolicyRuleAction.Builder, policy.Policy.PolicyRuleActionOrBuilder> 
-          getPolRuleActionListFieldBuilder() {
-        if (polRuleActionListBuilder_ == null) {
-          polRuleActionListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              policy.Policy.PolicyRuleAction, policy.Policy.PolicyRuleAction.Builder, policy.Policy.PolicyRuleActionOrBuilder>(
-                  polRuleActionList_,
+          policy.PolicyAction.PolicyRuleAction, policy.PolicyAction.PolicyRuleAction.Builder, policy.PolicyAction.PolicyRuleActionOrBuilder> 
+          getActionListFieldBuilder() {
+        if (actionListBuilder_ == null) {
+          actionListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              policy.PolicyAction.PolicyRuleAction, policy.PolicyAction.PolicyRuleAction.Builder, policy.PolicyAction.PolicyRuleActionOrBuilder>(
+                  actionList_,
                   ((bitField0_ & 0x00000002) != 0),
                   getParentForChildren(),
                   isClean());
-          polRuleActionList_ = null;
+          actionList_ = null;
         }
-        return polRuleActionListBuilder_;
-      }
-
-      private java.util.List<context.ContextOuterClass.ServiceId> serviceList_ =
-        java.util.Collections.emptyList();
-      private void ensureServiceListIsMutable() {
-        if (!((bitField0_ & 0x00000004) != 0)) {
-          serviceList_ = new java.util.ArrayList<context.ContextOuterClass.ServiceId>(serviceList_);
-          bitField0_ |= 0x00000004;
-         }
+        return actionListBuilder_;
       }
 
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> serviceListBuilder_;
-
-      /**
-       * <pre>
-       * Affected services and devices
-       * </pre>
-       *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
-       */
-      public java.util.List<context.ContextOuterClass.ServiceId> getServiceListList() {
-        if (serviceListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(serviceList_);
-        } else {
-          return serviceListBuilder_.getMessageList();
-        }
-      }
-      /**
-       * <pre>
-       * Affected services and devices
-       * </pre>
-       *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
-       */
-      public int getServiceListCount() {
-        if (serviceListBuilder_ == null) {
-          return serviceList_.size();
-        } else {
-          return serviceListBuilder_.getCount();
-        }
-      }
-      /**
-       * <pre>
-       * Affected services and devices
-       * </pre>
-       *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
-       */
-      public context.ContextOuterClass.ServiceId getServiceList(int index) {
-        if (serviceListBuilder_ == null) {
-          return serviceList_.get(index);
-        } else {
-          return serviceListBuilder_.getMessage(index);
-        }
-      }
-      /**
-       * <pre>
-       * Affected services and devices
-       * </pre>
-       *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
-       */
-      public Builder setServiceList(
-          int index, context.ContextOuterClass.ServiceId value) {
-        if (serviceListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureServiceListIsMutable();
-          serviceList_.set(index, value);
-          onChanged();
-        } else {
-          serviceListBuilder_.setMessage(index, value);
-        }
-        return this;
-      }
+      private context.ContextOuterClass.ServiceId serviceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> serviceIdBuilder_;
       /**
        * <pre>
-       * Affected services and devices
+       * Affected service and devices
        * </pre>
        *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
+       * <code>.context.ServiceId serviceId = 8;</code>
+       * @return Whether the serviceId field is set.
        */
-      public Builder setServiceList(
-          int index, context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceListBuilder_ == null) {
-          ensureServiceListIsMutable();
-          serviceList_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          serviceListBuilder_.setMessage(index, builderForValue.build());
-        }
-        return this;
+      public boolean hasServiceId() {
+        return serviceIdBuilder_ != null || serviceId_ != null;
       }
       /**
        * <pre>
-       * Affected services and devices
+       * Affected service and devices
        * </pre>
        *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
+       * <code>.context.ServiceId serviceId = 8;</code>
+       * @return The serviceId.
        */
-      public Builder addServiceList(context.ContextOuterClass.ServiceId value) {
-        if (serviceListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureServiceListIsMutable();
-          serviceList_.add(value);
-          onChanged();
+      public context.ContextOuterClass.ServiceId getServiceId() {
+        if (serviceIdBuilder_ == null) {
+          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
         } else {
-          serviceListBuilder_.addMessage(value);
+          return serviceIdBuilder_.getMessage();
         }
-        return this;
       }
       /**
        * <pre>
-       * Affected services and devices
+       * Affected service and devices
        * </pre>
        *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
+       * <code>.context.ServiceId serviceId = 8;</code>
        */
-      public Builder addServiceList(
-          int index, context.ContextOuterClass.ServiceId value) {
-        if (serviceListBuilder_ == null) {
+      public Builder setServiceId(context.ContextOuterClass.ServiceId value) {
+        if (serviceIdBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureServiceListIsMutable();
-          serviceList_.add(index, value);
+          serviceId_ = value;
           onChanged();
         } else {
-          serviceListBuilder_.addMessage(index, value);
+          serviceIdBuilder_.setMessage(value);
         }
+
         return this;
       }
       /**
        * <pre>
-       * Affected services and devices
+       * Affected service and devices
        * </pre>
        *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
+       * <code>.context.ServiceId serviceId = 8;</code>
        */
-      public Builder addServiceList(
+      public Builder setServiceId(
           context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceListBuilder_ == null) {
-          ensureServiceListIsMutable();
-          serviceList_.add(builderForValue.build());
-          onChanged();
-        } else {
-          serviceListBuilder_.addMessage(builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <pre>
-       * Affected services and devices
-       * </pre>
-       *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
-       */
-      public Builder addServiceList(
-          int index, context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceListBuilder_ == null) {
-          ensureServiceListIsMutable();
-          serviceList_.add(index, builderForValue.build());
-          onChanged();
-        } else {
-          serviceListBuilder_.addMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <pre>
-       * Affected services and devices
-       * </pre>
-       *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
-       */
-      public Builder addAllServiceList(
-          java.lang.Iterable<? extends context.ContextOuterClass.ServiceId> values) {
-        if (serviceListBuilder_ == null) {
-          ensureServiceListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, serviceList_);
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = builderForValue.build();
           onChanged();
         } else {
-          serviceListBuilder_.addAllMessages(values);
+          serviceIdBuilder_.setMessage(builderForValue.build());
         }
+
         return this;
       }
       /**
        * <pre>
-       * Affected services and devices
+       * Affected service and devices
        * </pre>
        *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
+       * <code>.context.ServiceId serviceId = 8;</code>
        */
-      public Builder clearServiceList() {
-        if (serviceListBuilder_ == null) {
-          serviceList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000004);
+      public Builder mergeServiceId(context.ContextOuterClass.ServiceId value) {
+        if (serviceIdBuilder_ == null) {
+          if (serviceId_ != null) {
+            serviceId_ =
+              context.ContextOuterClass.ServiceId.newBuilder(serviceId_).mergeFrom(value).buildPartial();
+          } else {
+            serviceId_ = value;
+          }
           onChanged();
         } else {
-          serviceListBuilder_.clear();
+          serviceIdBuilder_.mergeFrom(value);
         }
+
         return this;
       }
       /**
        * <pre>
-       * Affected services and devices
+       * Affected service and devices
        * </pre>
        *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
+       * <code>.context.ServiceId serviceId = 8;</code>
        */
-      public Builder removeServiceList(int index) {
-        if (serviceListBuilder_ == null) {
-          ensureServiceListIsMutable();
-          serviceList_.remove(index);
+      public Builder clearServiceId() {
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = null;
           onChanged();
         } else {
-          serviceListBuilder_.remove(index);
+          serviceId_ = null;
+          serviceIdBuilder_ = null;
         }
+
         return this;
       }
       /**
        * <pre>
-       * Affected services and devices
-       * </pre>
-       *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
-       */
-      public context.ContextOuterClass.ServiceId.Builder getServiceListBuilder(
-          int index) {
-        return getServiceListFieldBuilder().getBuilder(index);
-      }
-      /**
-       * <pre>
-       * Affected services and devices
+       * Affected service and devices
        * </pre>
        *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
+       * <code>.context.ServiceId serviceId = 8;</code>
        */
-      public context.ContextOuterClass.ServiceIdOrBuilder getServiceListOrBuilder(
-          int index) {
-        if (serviceListBuilder_ == null) {
-          return serviceList_.get(index);  } else {
-          return serviceListBuilder_.getMessageOrBuilder(index);
-        }
+      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
+        
+        onChanged();
+        return getServiceIdFieldBuilder().getBuilder();
       }
       /**
        * <pre>
-       * Affected services and devices
+       * Affected service and devices
        * </pre>
        *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
+       * <code>.context.ServiceId serviceId = 8;</code>
        */
-      public java.util.List<? extends context.ContextOuterClass.ServiceIdOrBuilder> 
-           getServiceListOrBuilderList() {
-        if (serviceListBuilder_ != null) {
-          return serviceListBuilder_.getMessageOrBuilderList();
+      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
+        if (serviceIdBuilder_ != null) {
+          return serviceIdBuilder_.getMessageOrBuilder();
         } else {
-          return java.util.Collections.unmodifiableList(serviceList_);
+          return serviceId_ == null ?
+              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
         }
       }
       /**
        * <pre>
-       * Affected services and devices
-       * </pre>
-       *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
-       */
-      public context.ContextOuterClass.ServiceId.Builder addServiceListBuilder() {
-        return getServiceListFieldBuilder().addBuilder(
-            context.ContextOuterClass.ServiceId.getDefaultInstance());
-      }
-      /**
-       * <pre>
-       * Affected services and devices
-       * </pre>
-       *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
-       */
-      public context.ContextOuterClass.ServiceId.Builder addServiceListBuilder(
-          int index) {
-        return getServiceListFieldBuilder().addBuilder(
-            index, context.ContextOuterClass.ServiceId.getDefaultInstance());
-      }
-      /**
-       * <pre>
-       * Affected services and devices
+       * Affected service and devices
        * </pre>
        *
-       * <code>repeated .context.ServiceId serviceList = 7;</code>
+       * <code>.context.ServiceId serviceId = 8;</code>
        */
-      public java.util.List<context.ContextOuterClass.ServiceId.Builder> 
-           getServiceListBuilderList() {
-        return getServiceListFieldBuilder().getBuilderList();
-      }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
+      private com.google.protobuf.SingleFieldBuilderV3<
           context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> 
-          getServiceListFieldBuilder() {
-        if (serviceListBuilder_ == null) {
-          serviceListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+          getServiceIdFieldBuilder() {
+        if (serviceIdBuilder_ == null) {
+          serviceIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
               context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder>(
-                  serviceList_,
-                  ((bitField0_ & 0x00000004) != 0),
+                  getServiceId(),
                   getParentForChildren(),
                   isClean());
-          serviceList_ = null;
+          serviceId_ = null;
         }
-        return serviceListBuilder_;
+        return serviceIdBuilder_;
       }
 
       private java.util.List<context.ContextOuterClass.DeviceId> deviceList_ =
         java.util.Collections.emptyList();
       private void ensureDeviceListIsMutable() {
-        if (!((bitField0_ & 0x00000008) != 0)) {
+        if (!((bitField0_ & 0x00000004) != 0)) {
           deviceList_ = new java.util.ArrayList<context.ContextOuterClass.DeviceId>(deviceList_);
-          bitField0_ |= 0x00000008;
+          bitField0_ |= 0x00000004;
          }
       }
 
@@ -7744,7 +4866,7 @@ public final class Policy {
           context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder> deviceListBuilder_;
 
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public java.util.List<context.ContextOuterClass.DeviceId> getDeviceListList() {
         if (deviceListBuilder_ == null) {
@@ -7754,7 +4876,7 @@ public final class Policy {
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public int getDeviceListCount() {
         if (deviceListBuilder_ == null) {
@@ -7764,7 +4886,7 @@ public final class Policy {
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public context.ContextOuterClass.DeviceId getDeviceList(int index) {
         if (deviceListBuilder_ == null) {
@@ -7774,7 +4896,7 @@ public final class Policy {
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public Builder setDeviceList(
           int index, context.ContextOuterClass.DeviceId value) {
@@ -7791,7 +4913,7 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public Builder setDeviceList(
           int index, context.ContextOuterClass.DeviceId.Builder builderForValue) {
@@ -7805,7 +4927,7 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public Builder addDeviceList(context.ContextOuterClass.DeviceId value) {
         if (deviceListBuilder_ == null) {
@@ -7821,7 +4943,7 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public Builder addDeviceList(
           int index, context.ContextOuterClass.DeviceId value) {
@@ -7838,7 +4960,7 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public Builder addDeviceList(
           context.ContextOuterClass.DeviceId.Builder builderForValue) {
@@ -7852,7 +4974,7 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public Builder addDeviceList(
           int index, context.ContextOuterClass.DeviceId.Builder builderForValue) {
@@ -7866,7 +4988,7 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public Builder addAllDeviceList(
           java.lang.Iterable<? extends context.ContextOuterClass.DeviceId> values) {
@@ -7881,12 +5003,12 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public Builder clearDeviceList() {
         if (deviceListBuilder_ == null) {
           deviceList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000008);
+          bitField0_ = (bitField0_ & ~0x00000004);
           onChanged();
         } else {
           deviceListBuilder_.clear();
@@ -7894,7 +5016,7 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public Builder removeDeviceList(int index) {
         if (deviceListBuilder_ == null) {
@@ -7907,14 +5029,14 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public context.ContextOuterClass.DeviceId.Builder getDeviceListBuilder(
           int index) {
         return getDeviceListFieldBuilder().getBuilder(index);
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
           int index) {
@@ -7924,7 +5046,7 @@ public final class Policy {
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
            getDeviceListOrBuilderList() {
@@ -7935,14 +5057,14 @@ public final class Policy {
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public context.ContextOuterClass.DeviceId.Builder addDeviceListBuilder() {
         return getDeviceListFieldBuilder().addBuilder(
             context.ContextOuterClass.DeviceId.getDefaultInstance());
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public context.ContextOuterClass.DeviceId.Builder addDeviceListBuilder(
           int index) {
@@ -7950,7 +5072,7 @@ public final class Policy {
             index, context.ContextOuterClass.DeviceId.getDefaultInstance());
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 8;</code>
+       * <code>repeated .context.DeviceId deviceList = 9;</code>
        */
       public java.util.List<context.ContextOuterClass.DeviceId.Builder> 
            getDeviceListBuilderList() {
@@ -7963,7 +5085,7 @@ public final class Policy {
           deviceListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
               context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder>(
                   deviceList_,
-                  ((bitField0_ & 0x00000008) != 0),
+                  ((bitField0_ & 0x00000004) != 0),
                   getParentForChildren(),
                   isClean());
           deviceList_ = null;
@@ -8834,31 +5956,11 @@ public final class Policy {
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_policy_PolicyRuleState_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_policy_PolicyRuleVariable_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_policy_PolicyRuleVariable_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_policy_PolicyRuleValue_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_policy_PolicyRuleValue_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_policy_PolicyRuleEvent_descriptor;
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_policy_PolicyRuleEvent_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_policy_PolicyRuleCondition_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_policy_PolicyRuleCondition_fieldAccessorTable;
-  private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_policy_PolicyRuleAction_descriptor;
-  private static final 
-    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_policy_PolicyRuleAction_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
     internal_static_policy_PolicyRule_descriptor;
   private static final 
@@ -8878,50 +5980,45 @@ public final class Policy {
       descriptor;
   static {
     java.lang.String[] descriptorData = {
-      "\n\014policy.proto\022\006policy\032\rcontext.proto\"+\n" +
-      "\014PolicyRuleId\022\033\n\004uuid\030\001 \001(\0132\r.context.Uu" +
-      "id\"b\n\017PolicyRuleState\022#\n\014policyRuleId\030\001 " +
-      "\001(\0132\r.context.Uuid\022*\n\017policyRuleState\030\002 " +
-      "\001(\0162\021.policy.RuleState\"0\n\022PolicyRuleVari" +
-      "able\022\032\n\022policyRuleVariable\030\001 \001(\t\"*\n\017Poli" +
-      "cyRuleValue\022\027\n\017policyRuleValue\030\001 \001(\t\"0\n\017" +
-      "PolicyRuleEvent\022\035\n\005event\030\001 \001(\0132\016.context" +
-      ".Event\"\204\001\n\023PolicyRuleCondition\0227\n\023polRul" +
-      "eConditionVar\030\001 \001(\0132\032.policy.PolicyRuleV" +
-      "ariable\0224\n\023polRuleConditionVal\030\002 \001(\0132\027.p" +
-      "olicy.PolicyRuleValue\"{\n\020PolicyRuleActio" +
-      "n\0224\n\020polRuleActionVar\030\001 \001(\0132\032.policy.Pol" +
-      "icyRuleVariable\0221\n\020polRuleActionVal\030\002 \001(" +
-      "\0132\027.policy.PolicyRuleValue\"\354\002\n\nPolicyRul" +
-      "e\022*\n\014policyRuleId\030\001 \001(\0132\024.policy.PolicyR" +
-      "uleId\022.\n\016policyRuleType\030\002 \001(\0162\026.policy.P" +
-      "olicyRuleType\022\032\n\022PolicyRulePriority\030\003 \001(" +
-      "\r\022&\n\005event\030\004 \001(\0132\027.policy.PolicyRuleEven" +
-      "t\0229\n\024polRuleConditionList\030\005 \003(\0132\033.policy" +
-      ".PolicyRuleCondition\0223\n\021polRuleActionLis" +
-      "t\030\006 \003(\0132\030.policy.PolicyRuleAction\022\'\n\013ser" +
-      "viceList\030\007 \003(\0132\022.context.ServiceId\022%\n\nde" +
-      "viceList\030\010 \003(\0132\021.context.DeviceId\"<\n\016Pol" +
-      "icyRuleList\022*\n\016policyRuleList\030\001 \003(\0132\022.po" +
-      "licy.PolicyRule*G\n\tRuleState\022\023\n\017POLICY_I" +
-      "NACTIVE\020\000\022\022\n\016POLICY_PLANNED\020\001\022\021\n\rPOLICY_" +
-      "ACTIVE\020\002*?\n\016PolicyRuleType\022\025\n\021POLICYTYPE" +
-      "_DEVICE\020\000\022\026\n\022POLICYTYPE_NETWORK\020\0012\214\003\n\rPo" +
-      "licyService\022:\n\tPolicyAdd\022\022.policy.Policy" +
-      "Rule\032\027.policy.PolicyRuleState\"\000\022=\n\014Polic" +
-      "yUpdate\022\022.policy.PolicyRule\032\027.policy.Pol" +
-      "icyRuleState\"\000\022=\n\014PolicyDelete\022\022.policy." +
-      "PolicyRule\032\027.policy.PolicyRuleState\"\000\0227\n" +
-      "\tGetPolicy\022\024.policy.PolicyRuleId\032\022.polic" +
-      "y.PolicyRule\"\000\022B\n\023GetPolicyByDeviceId\022\021." +
-      "context.DeviceId\032\026.policy.PolicyRuleList" +
-      "\"\000\022D\n\024GetPolicyByServiceId\022\022.context.Ser" +
-      "viceId\032\026.policy.PolicyRuleList\"\000b\006proto3"
+      "\n\014policy.proto\022\006policy\032\rcontext.proto\032\026p" +
+      "olicy-condition.proto\032\023policy-action.pro" +
+      "to\"+\n\014PolicyRuleId\022\033\n\004uuid\030\001 \001(\0132\r.conte" +
+      "xt.Uuid\"b\n\017PolicyRuleState\022#\n\014policyRule" +
+      "Id\030\001 \001(\0132\r.context.Uuid\022*\n\017policyRuleSta" +
+      "te\030\002 \001(\0162\021.policy.RuleState\"0\n\017PolicyRul" +
+      "eEvent\022\035\n\005event\030\001 \001(\0132\016.context.Event\"\204\003" +
+      "\n\nPolicyRule\022*\n\014policyRuleId\030\001 \001(\0132\024.pol" +
+      "icy.PolicyRuleId\022.\n\016policyRuleType\030\002 \001(\016" +
+      "2\026.policy.PolicyRuleType\022\020\n\010priority\030\003 \001" +
+      "(\r\022&\n\005event\030\004 \001(\0132\027.policy.PolicyRuleEve" +
+      "nt\0222\n\rconditionList\030\005 \003(\0132\033.policy.Polic" +
+      "yRuleCondition\0220\n\017booleanOperator\030\006 \001(\0162" +
+      "\027.policy.BooleanOperator\022,\n\nactionList\030\007" +
+      " \003(\0132\030.policy.PolicyRuleAction\022%\n\tservic" +
+      "eId\030\010 \001(\0132\022.context.ServiceId\022%\n\ndeviceL" +
+      "ist\030\t \003(\0132\021.context.DeviceId\"<\n\016PolicyRu" +
+      "leList\022*\n\016policyRuleList\030\001 \003(\0132\022.policy." +
+      "PolicyRule*G\n\tRuleState\022\023\n\017POLICY_INACTI" +
+      "VE\020\000\022\022\n\016POLICY_PLANNED\020\001\022\021\n\rPOLICY_ACTIV" +
+      "E\020\002*?\n\016PolicyRuleType\022\025\n\021POLICYTYPE_DEVI" +
+      "CE\020\000\022\026\n\022POLICYTYPE_NETWORK\020\0012\214\003\n\rPolicyS" +
+      "ervice\022:\n\tPolicyAdd\022\022.policy.PolicyRule\032" +
+      "\027.policy.PolicyRuleState\"\000\022=\n\014PolicyUpda" +
+      "te\022\022.policy.PolicyRule\032\027.policy.PolicyRu" +
+      "leState\"\000\022=\n\014PolicyDelete\022\022.policy.Polic" +
+      "yRule\032\027.policy.PolicyRuleState\"\000\0227\n\tGetP" +
+      "olicy\022\024.policy.PolicyRuleId\032\022.policy.Pol" +
+      "icyRule\"\000\022B\n\023GetPolicyByDeviceId\022\021.conte" +
+      "xt.DeviceId\032\026.policy.PolicyRuleList\"\000\022D\n" +
+      "\024GetPolicyByServiceId\022\022.context.ServiceI" +
+      "d\032\026.policy.PolicyRuleList\"\000b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
         new com.google.protobuf.Descriptors.FileDescriptor[] {
           context.ContextOuterClass.getDescriptor(),
+          policy.PolicyCondition.getDescriptor(),
+          policy.PolicyAction.getDescriptor(),
         });
     internal_static_policy_PolicyRuleId_descriptor =
       getDescriptor().getMessageTypes().get(0);
@@ -8935,49 +6032,27 @@ public final class Policy {
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_policy_PolicyRuleState_descriptor,
         new java.lang.String[] { "PolicyRuleId", "PolicyRuleState", });
-    internal_static_policy_PolicyRuleVariable_descriptor =
-      getDescriptor().getMessageTypes().get(2);
-    internal_static_policy_PolicyRuleVariable_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_policy_PolicyRuleVariable_descriptor,
-        new java.lang.String[] { "PolicyRuleVariable", });
-    internal_static_policy_PolicyRuleValue_descriptor =
-      getDescriptor().getMessageTypes().get(3);
-    internal_static_policy_PolicyRuleValue_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_policy_PolicyRuleValue_descriptor,
-        new java.lang.String[] { "PolicyRuleValue", });
     internal_static_policy_PolicyRuleEvent_descriptor =
-      getDescriptor().getMessageTypes().get(4);
+      getDescriptor().getMessageTypes().get(2);
     internal_static_policy_PolicyRuleEvent_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_policy_PolicyRuleEvent_descriptor,
         new java.lang.String[] { "Event", });
-    internal_static_policy_PolicyRuleCondition_descriptor =
-      getDescriptor().getMessageTypes().get(5);
-    internal_static_policy_PolicyRuleCondition_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_policy_PolicyRuleCondition_descriptor,
-        new java.lang.String[] { "PolRuleConditionVar", "PolRuleConditionVal", });
-    internal_static_policy_PolicyRuleAction_descriptor =
-      getDescriptor().getMessageTypes().get(6);
-    internal_static_policy_PolicyRuleAction_fieldAccessorTable = new
-      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_policy_PolicyRuleAction_descriptor,
-        new java.lang.String[] { "PolRuleActionVar", "PolRuleActionVal", });
     internal_static_policy_PolicyRule_descriptor =
-      getDescriptor().getMessageTypes().get(7);
+      getDescriptor().getMessageTypes().get(3);
     internal_static_policy_PolicyRule_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_policy_PolicyRule_descriptor,
-        new java.lang.String[] { "PolicyRuleId", "PolicyRuleType", "PolicyRulePriority", "Event", "PolRuleConditionList", "PolRuleActionList", "ServiceList", "DeviceList", });
+        new java.lang.String[] { "PolicyRuleId", "PolicyRuleType", "Priority", "Event", "ConditionList", "BooleanOperator", "ActionList", "ServiceId", "DeviceList", });
     internal_static_policy_PolicyRuleList_descriptor =
-      getDescriptor().getMessageTypes().get(8);
+      getDescriptor().getMessageTypes().get(4);
     internal_static_policy_PolicyRuleList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_policy_PolicyRuleList_descriptor,
         new java.lang.String[] { "PolicyRuleList", });
     context.ContextOuterClass.getDescriptor();
+    policy.PolicyCondition.getDescriptor();
+    policy.PolicyAction.getDescriptor();
   }
 
   // @@protoc_insertion_point(outer_class_scope)
diff --git a/src/policy/target/generated-sources/grpc/policy/PolicyAction.java b/src/policy/target/generated-sources/grpc/policy/PolicyAction.java
new file mode 100644
index 000000000..1baaf538d
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/policy/PolicyAction.java
@@ -0,0 +1,932 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: policy-action.proto
+
+package policy;
+
+public final class PolicyAction {
+  private PolicyAction() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+  /**
+   * Protobuf enum {@code policy.PolicyRuleActionEnum}
+   */
+  public enum PolicyRuleActionEnum
+      implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <code>POLICYRULE_ACTION_NO_ACTION = 0;</code>
+     */
+    POLICYRULE_ACTION_NO_ACTION(0),
+    /**
+     * <code>POLICYRULE_ACTION_SET_DEVICE_STATUS = 1;</code>
+     */
+    POLICYRULE_ACTION_SET_DEVICE_STATUS(1),
+    /**
+     * <code>POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE = 2;</code>
+     */
+    POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE(2),
+    /**
+     * <code>POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT = 3;</code>
+     */
+    POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT(3),
+    UNRECOGNIZED(-1),
+    ;
+
+    /**
+     * <code>POLICYRULE_ACTION_NO_ACTION = 0;</code>
+     */
+    public static final int POLICYRULE_ACTION_NO_ACTION_VALUE = 0;
+    /**
+     * <code>POLICYRULE_ACTION_SET_DEVICE_STATUS = 1;</code>
+     */
+    public static final int POLICYRULE_ACTION_SET_DEVICE_STATUS_VALUE = 1;
+    /**
+     * <code>POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE = 2;</code>
+     */
+    public static final int POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE_VALUE = 2;
+    /**
+     * <code>POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT = 3;</code>
+     */
+    public static final int POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT_VALUE = 3;
+
+
+    public final int getNumber() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalArgumentException(
+            "Can't get the number of an unknown enum value.");
+      }
+      return value;
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     * @deprecated Use {@link #forNumber(int)} instead.
+     */
+    @java.lang.Deprecated
+    public static PolicyRuleActionEnum valueOf(int value) {
+      return forNumber(value);
+    }
+
+    /**
+     * @param value The numeric wire value of the corresponding enum entry.
+     * @return The enum associated with the given numeric wire value.
+     */
+    public static PolicyRuleActionEnum forNumber(int value) {
+      switch (value) {
+        case 0: return POLICYRULE_ACTION_NO_ACTION;
+        case 1: return POLICYRULE_ACTION_SET_DEVICE_STATUS;
+        case 2: return POLICYRULE_ACTION_ADD_SERVICE_CONFIGRULE;
+        case 3: return POLICYRULE_ACTION_ADD_SERVICE_CONSTRAINT;
+        default: return null;
+      }
+    }
+
+    public static com.google.protobuf.Internal.EnumLiteMap<PolicyRuleActionEnum>
+        internalGetValueMap() {
+      return internalValueMap;
+    }
+    private static final com.google.protobuf.Internal.EnumLiteMap<
+        PolicyRuleActionEnum> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<PolicyRuleActionEnum>() {
+            public PolicyRuleActionEnum findValueByNumber(int number) {
+              return PolicyRuleActionEnum.forNumber(number);
+            }
+          };
+
+    public final com.google.protobuf.Descriptors.EnumValueDescriptor
+        getValueDescriptor() {
+      if (this == UNRECOGNIZED) {
+        throw new java.lang.IllegalStateException(
+            "Can't get the descriptor of an unrecognized enum value.");
+      }
+      return getDescriptor().getValues().get(ordinal());
+    }
+    public final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptorForType() {
+      return getDescriptor();
+    }
+    public static final com.google.protobuf.Descriptors.EnumDescriptor
+        getDescriptor() {
+      return policy.PolicyAction.getDescriptor().getEnumTypes().get(0);
+    }
+
+    private static final PolicyRuleActionEnum[] VALUES = values();
+
+    public static PolicyRuleActionEnum valueOf(
+        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
+      if (desc.getType() != getDescriptor()) {
+        throw new java.lang.IllegalArgumentException(
+          "EnumValueDescriptor is not for this type.");
+      }
+      if (desc.getIndex() == -1) {
+        return UNRECOGNIZED;
+      }
+      return VALUES[desc.getIndex()];
+    }
+
+    private final int value;
+
+    private PolicyRuleActionEnum(int value) {
+      this.value = value;
+    }
+
+    // @@protoc_insertion_point(enum_scope:policy.PolicyRuleActionEnum)
+  }
+
+  public interface PolicyRuleActionOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleAction)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>.policy.PolicyRuleActionEnum action = 1;</code>
+     * @return The enum numeric value on the wire for action.
+     */
+    int getActionValue();
+    /**
+     * <code>.policy.PolicyRuleActionEnum action = 1;</code>
+     * @return The action.
+     */
+    policy.PolicyAction.PolicyRuleActionEnum getAction();
+
+    /**
+     * <code>repeated string parameters = 2;</code>
+     * @return A list containing the parameters.
+     */
+    java.util.List<java.lang.String>
+        getParametersList();
+    /**
+     * <code>repeated string parameters = 2;</code>
+     * @return The count of parameters.
+     */
+    int getParametersCount();
+    /**
+     * <code>repeated string parameters = 2;</code>
+     * @param index The index of the element to return.
+     * @return The parameters at the given index.
+     */
+    java.lang.String getParameters(int index);
+    /**
+     * <code>repeated string parameters = 2;</code>
+     * @param index The index of the value to return.
+     * @return The bytes of the parameters at the given index.
+     */
+    com.google.protobuf.ByteString
+        getParametersBytes(int index);
+  }
+  /**
+   * <pre>
+   * Action
+   * </pre>
+   *
+   * Protobuf type {@code policy.PolicyRuleAction}
+   */
+  public static final class PolicyRuleAction extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:policy.PolicyRuleAction)
+      PolicyRuleActionOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use PolicyRuleAction.newBuilder() to construct.
+    private PolicyRuleAction(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private PolicyRuleAction() {
+      action_ = 0;
+      parameters_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new PolicyRuleAction();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PolicyRuleAction(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 8: {
+              int rawValue = input.readEnum();
+
+              action_ = rawValue;
+              break;
+            }
+            case 18: {
+              java.lang.String s = input.readStringRequireUtf8();
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                parameters_ = new com.google.protobuf.LazyStringArrayList();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              parameters_.add(s);
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          parameters_ = parameters_.getUnmodifiableView();
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return policy.PolicyAction.internal_static_policy_PolicyRuleAction_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return policy.PolicyAction.internal_static_policy_PolicyRuleAction_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              policy.PolicyAction.PolicyRuleAction.class, policy.PolicyAction.PolicyRuleAction.Builder.class);
+    }
+
+    public static final int ACTION_FIELD_NUMBER = 1;
+    private int action_;
+    /**
+     * <code>.policy.PolicyRuleActionEnum action = 1;</code>
+     * @return The enum numeric value on the wire for action.
+     */
+    @java.lang.Override public int getActionValue() {
+      return action_;
+    }
+    /**
+     * <code>.policy.PolicyRuleActionEnum action = 1;</code>
+     * @return The action.
+     */
+    @java.lang.Override public policy.PolicyAction.PolicyRuleActionEnum getAction() {
+      @SuppressWarnings("deprecation")
+      policy.PolicyAction.PolicyRuleActionEnum result = policy.PolicyAction.PolicyRuleActionEnum.valueOf(action_);
+      return result == null ? policy.PolicyAction.PolicyRuleActionEnum.UNRECOGNIZED : result;
+    }
+
+    public static final int PARAMETERS_FIELD_NUMBER = 2;
+    private com.google.protobuf.LazyStringList parameters_;
+    /**
+     * <code>repeated string parameters = 2;</code>
+     * @return A list containing the parameters.
+     */
+    public com.google.protobuf.ProtocolStringList
+        getParametersList() {
+      return parameters_;
+    }
+    /**
+     * <code>repeated string parameters = 2;</code>
+     * @return The count of parameters.
+     */
+    public int getParametersCount() {
+      return parameters_.size();
+    }
+    /**
+     * <code>repeated string parameters = 2;</code>
+     * @param index The index of the element to return.
+     * @return The parameters at the given index.
+     */
+    public java.lang.String getParameters(int index) {
+      return parameters_.get(index);
+    }
+    /**
+     * <code>repeated string parameters = 2;</code>
+     * @param index The index of the value to return.
+     * @return The bytes of the parameters at the given index.
+     */
+    public com.google.protobuf.ByteString
+        getParametersBytes(int index) {
+      return parameters_.getByteString(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (action_ != policy.PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_NO_ACTION.getNumber()) {
+        output.writeEnum(1, action_);
+      }
+      for (int i = 0; i < parameters_.size(); i++) {
+        com.google.protobuf.GeneratedMessageV3.writeString(output, 2, parameters_.getRaw(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (action_ != policy.PolicyAction.PolicyRuleActionEnum.POLICYRULE_ACTION_NO_ACTION.getNumber()) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeEnumSize(1, action_);
+      }
+      {
+        int dataSize = 0;
+        for (int i = 0; i < parameters_.size(); i++) {
+          dataSize += computeStringSizeNoTag(parameters_.getRaw(i));
+        }
+        size += dataSize;
+        size += 1 * getParametersList().size();
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof policy.PolicyAction.PolicyRuleAction)) {
+        return super.equals(obj);
+      }
+      policy.PolicyAction.PolicyRuleAction other = (policy.PolicyAction.PolicyRuleAction) obj;
+
+      if (action_ != other.action_) return false;
+      if (!getParametersList()
+          .equals(other.getParametersList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      hash = (37 * hash) + ACTION_FIELD_NUMBER;
+      hash = (53 * hash) + action_;
+      if (getParametersCount() > 0) {
+        hash = (37 * hash) + PARAMETERS_FIELD_NUMBER;
+        hash = (53 * hash) + getParametersList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.PolicyAction.PolicyRuleAction parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(policy.PolicyAction.PolicyRuleAction prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * Action
+     * </pre>
+     *
+     * Protobuf type {@code policy.PolicyRuleAction}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleAction)
+        policy.PolicyAction.PolicyRuleActionOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return policy.PolicyAction.internal_static_policy_PolicyRuleAction_descriptor;
+      }
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return policy.PolicyAction.internal_static_policy_PolicyRuleAction_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                policy.PolicyAction.PolicyRuleAction.class, policy.PolicyAction.PolicyRuleAction.Builder.class);
+      }
+
+      // Construct using policy.PolicyAction.PolicyRuleAction.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        action_ = 0;
+
+        parameters_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return policy.PolicyAction.internal_static_policy_PolicyRuleAction_descriptor;
+      }
+
+      @java.lang.Override
+      public policy.PolicyAction.PolicyRuleAction getDefaultInstanceForType() {
+        return policy.PolicyAction.PolicyRuleAction.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public policy.PolicyAction.PolicyRuleAction build() {
+        policy.PolicyAction.PolicyRuleAction result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public policy.PolicyAction.PolicyRuleAction buildPartial() {
+        policy.PolicyAction.PolicyRuleAction result = new policy.PolicyAction.PolicyRuleAction(this);
+        int from_bitField0_ = bitField0_;
+        result.action_ = action_;
+        if (((bitField0_ & 0x00000001) != 0)) {
+          parameters_ = parameters_.getUnmodifiableView();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        }
+        result.parameters_ = parameters_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof policy.PolicyAction.PolicyRuleAction) {
+          return mergeFrom((policy.PolicyAction.PolicyRuleAction)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(policy.PolicyAction.PolicyRuleAction other) {
+        if (other == policy.PolicyAction.PolicyRuleAction.getDefaultInstance()) return this;
+        if (other.action_ != 0) {
+          setActionValue(other.getActionValue());
+        }
+        if (!other.parameters_.isEmpty()) {
+          if (parameters_.isEmpty()) {
+            parameters_ = other.parameters_;
+            bitField0_ = (bitField0_ & ~0x00000001);
+          } else {
+            ensureParametersIsMutable();
+            parameters_.addAll(other.parameters_);
+          }
+          onChanged();
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        policy.PolicyAction.PolicyRuleAction parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (policy.PolicyAction.PolicyRuleAction) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
+
+      private int action_ = 0;
+      /**
+       * <code>.policy.PolicyRuleActionEnum action = 1;</code>
+       * @return The enum numeric value on the wire for action.
+       */
+      @java.lang.Override public int getActionValue() {
+        return action_;
+      }
+      /**
+       * <code>.policy.PolicyRuleActionEnum action = 1;</code>
+       * @param value The enum numeric value on the wire for action to set.
+       * @return This builder for chaining.
+       */
+      public Builder setActionValue(int value) {
+        
+        action_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.policy.PolicyRuleActionEnum action = 1;</code>
+       * @return The action.
+       */
+      @java.lang.Override
+      public policy.PolicyAction.PolicyRuleActionEnum getAction() {
+        @SuppressWarnings("deprecation")
+        policy.PolicyAction.PolicyRuleActionEnum result = policy.PolicyAction.PolicyRuleActionEnum.valueOf(action_);
+        return result == null ? policy.PolicyAction.PolicyRuleActionEnum.UNRECOGNIZED : result;
+      }
+      /**
+       * <code>.policy.PolicyRuleActionEnum action = 1;</code>
+       * @param value The action to set.
+       * @return This builder for chaining.
+       */
+      public Builder setAction(policy.PolicyAction.PolicyRuleActionEnum value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        
+        action_ = value.getNumber();
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>.policy.PolicyRuleActionEnum action = 1;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearAction() {
+        
+        action_ = 0;
+        onChanged();
+        return this;
+      }
+
+      private com.google.protobuf.LazyStringList parameters_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+      private void ensureParametersIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          parameters_ = new com.google.protobuf.LazyStringArrayList(parameters_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+      /**
+       * <code>repeated string parameters = 2;</code>
+       * @return A list containing the parameters.
+       */
+      public com.google.protobuf.ProtocolStringList
+          getParametersList() {
+        return parameters_.getUnmodifiableView();
+      }
+      /**
+       * <code>repeated string parameters = 2;</code>
+       * @return The count of parameters.
+       */
+      public int getParametersCount() {
+        return parameters_.size();
+      }
+      /**
+       * <code>repeated string parameters = 2;</code>
+       * @param index The index of the element to return.
+       * @return The parameters at the given index.
+       */
+      public java.lang.String getParameters(int index) {
+        return parameters_.get(index);
+      }
+      /**
+       * <code>repeated string parameters = 2;</code>
+       * @param index The index of the value to return.
+       * @return The bytes of the parameters at the given index.
+       */
+      public com.google.protobuf.ByteString
+          getParametersBytes(int index) {
+        return parameters_.getByteString(index);
+      }
+      /**
+       * <code>repeated string parameters = 2;</code>
+       * @param index The index to set the value at.
+       * @param value The parameters to set.
+       * @return This builder for chaining.
+       */
+      public Builder setParameters(
+          int index, java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureParametersIsMutable();
+        parameters_.set(index, value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string parameters = 2;</code>
+       * @param value The parameters to add.
+       * @return This builder for chaining.
+       */
+      public Builder addParameters(
+          java.lang.String value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  ensureParametersIsMutable();
+        parameters_.add(value);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string parameters = 2;</code>
+       * @param values The parameters to add.
+       * @return This builder for chaining.
+       */
+      public Builder addAllParameters(
+          java.lang.Iterable<java.lang.String> values) {
+        ensureParametersIsMutable();
+        com.google.protobuf.AbstractMessageLite.Builder.addAll(
+            values, parameters_);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string parameters = 2;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearParameters() {
+        parameters_ = com.google.protobuf.LazyStringArrayList.EMPTY;
+        bitField0_ = (bitField0_ & ~0x00000001);
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>repeated string parameters = 2;</code>
+       * @param value The bytes of the parameters to add.
+       * @return This builder for chaining.
+       */
+      public Builder addParametersBytes(
+          com.google.protobuf.ByteString value) {
+        if (value == null) {
+    throw new NullPointerException();
+  }
+  checkByteStringIsUtf8(value);
+        ensureParametersIsMutable();
+        parameters_.add(value);
+        onChanged();
+        return this;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleAction)
+    }
+
+    // @@protoc_insertion_point(class_scope:policy.PolicyRuleAction)
+    private static final policy.PolicyAction.PolicyRuleAction DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new policy.PolicyAction.PolicyRuleAction();
+    }
+
+    public static policy.PolicyAction.PolicyRuleAction getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<PolicyRuleAction>
+        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleAction>() {
+      @java.lang.Override
+      public PolicyRuleAction parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PolicyRuleAction(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<PolicyRuleAction> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PolicyRuleAction> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public policy.PolicyAction.PolicyRuleAction getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_policy_PolicyRuleAction_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_policy_PolicyRuleAction_fieldAccessorTable;
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\023policy-action.proto\022\006policy\"T\n\020PolicyR" +
+      "uleAction\022,\n\006action\030\001 \001(\0162\034.policy.Polic" +
+      "yRuleActionEnum\022\022\n\nparameters\030\002 \003(\t*\274\001\n\024" +
+      "PolicyRuleActionEnum\022\037\n\033POLICYRULE_ACTIO" +
+      "N_NO_ACTION\020\000\022\'\n#POLICYRULE_ACTION_SET_D" +
+      "EVICE_STATUS\020\001\022,\n(POLICYRULE_ACTION_ADD_" +
+      "SERVICE_CONFIGRULE\020\002\022,\n(POLICYRULE_ACTIO" +
+      "N_ADD_SERVICE_CONSTRAINT\020\003b\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+        });
+    internal_static_policy_PolicyRuleAction_descriptor =
+      getDescriptor().getMessageTypes().get(0);
+    internal_static_policy_PolicyRuleAction_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_policy_PolicyRuleAction_descriptor,
+        new java.lang.String[] { "Action", "Parameters", });
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/policy/target/generated-sources/grpc/policy/PolicyCondition.java b/src/policy/target/generated-sources/grpc/policy/PolicyCondition.java
index 509c3db6a..2bde987ea 100644
--- a/src/policy/target/generated-sources/grpc/policy/PolicyCondition.java
+++ b/src/policy/target/generated-sources/grpc/policy/PolicyCondition.java
@@ -19,109 +19,125 @@ public final class PolicyCondition {
    * Operator to be used when comparing Kpis with condition values
    * </pre>
    *
-   * Protobuf enum {@code policy.PolicyRuleConditionComparisonOperator}
+   * Protobuf enum {@code policy.NumericalOperator}
    */
-  public enum PolicyRuleConditionComparisonOperator
+  public enum NumericalOperator
       implements com.google.protobuf.ProtocolMessageEnum {
+    /**
+     * <pre>
+     * Kpi numerical operator undefined
+     * </pre>
+     *
+     * <code>POLICYRULE_CONDITION_NUMERICAL_UNDEFINED = 0;</code>
+     */
+    POLICYRULE_CONDITION_NUMERICAL_UNDEFINED(0),
     /**
      * <pre>
      * Kpi is equal with value
      * </pre>
      *
-     * <code>EQUAL = 0;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_EQUAL = 1;</code>
      */
-    EQUAL(0),
+    POLICYRULE_CONDITION_NUMERICAL_EQUAL(1),
     /**
      * <pre>
      * Kpi is not equal with value
      * </pre>
      *
-     * <code>NOT_EQUAL = 1;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL = 2;</code>
      */
-    NOT_EQUAL(1),
+    POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL(2),
     /**
      * <pre>
      * Kpi is less than value
      * </pre>
      *
-     * <code>LESS_THAN = 2;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_LESS_THAN = 3;</code>
      */
-    LESS_THAN(2),
+    POLICYRULE_CONDITION_NUMERICAL_LESS_THAN(3),
     /**
      * <pre>
      * Kpi is less than or equal with value
      * </pre>
      *
-     * <code>LESS_THAN_EQUAL = 3;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL = 4;</code>
      */
-    LESS_THAN_EQUAL(3),
+    POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL(4),
     /**
      * <pre>
      * Kpi is greater than value
      * </pre>
      *
-     * <code>GREATER_THAN = 4;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN = 5;</code>
      */
-    GREATER_THAN(4),
+    POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN(5),
     /**
      * <pre>
      * Kpi is less than or equal with value
      * </pre>
      *
-     * <code>GREATER_THAN_EQUAL = 5;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL = 6;</code>
      */
-    GREATER_THAN_EQUAL(5),
+    POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL(6),
     UNRECOGNIZED(-1),
     ;
 
+    /**
+     * <pre>
+     * Kpi numerical operator undefined
+     * </pre>
+     *
+     * <code>POLICYRULE_CONDITION_NUMERICAL_UNDEFINED = 0;</code>
+     */
+    public static final int POLICYRULE_CONDITION_NUMERICAL_UNDEFINED_VALUE = 0;
     /**
      * <pre>
      * Kpi is equal with value
      * </pre>
      *
-     * <code>EQUAL = 0;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_EQUAL = 1;</code>
      */
-    public static final int EQUAL_VALUE = 0;
+    public static final int POLICYRULE_CONDITION_NUMERICAL_EQUAL_VALUE = 1;
     /**
      * <pre>
      * Kpi is not equal with value
      * </pre>
      *
-     * <code>NOT_EQUAL = 1;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL = 2;</code>
      */
-    public static final int NOT_EQUAL_VALUE = 1;
+    public static final int POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL_VALUE = 2;
     /**
      * <pre>
      * Kpi is less than value
      * </pre>
      *
-     * <code>LESS_THAN = 2;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_LESS_THAN = 3;</code>
      */
-    public static final int LESS_THAN_VALUE = 2;
+    public static final int POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_VALUE = 3;
     /**
      * <pre>
      * Kpi is less than or equal with value
      * </pre>
      *
-     * <code>LESS_THAN_EQUAL = 3;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL = 4;</code>
      */
-    public static final int LESS_THAN_EQUAL_VALUE = 3;
+    public static final int POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL_VALUE = 4;
     /**
      * <pre>
      * Kpi is greater than value
      * </pre>
      *
-     * <code>GREATER_THAN = 4;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN = 5;</code>
      */
-    public static final int GREATER_THAN_VALUE = 4;
+    public static final int POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_VALUE = 5;
     /**
      * <pre>
      * Kpi is less than or equal with value
      * </pre>
      *
-     * <code>GREATER_THAN_EQUAL = 5;</code>
+     * <code>POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL = 6;</code>
      */
-    public static final int GREATER_THAN_EQUAL_VALUE = 5;
+    public static final int POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL_VALUE = 6;
 
 
     public final int getNumber() {
@@ -138,7 +154,7 @@ public final class PolicyCondition {
      * @deprecated Use {@link #forNumber(int)} instead.
      */
     @java.lang.Deprecated
-    public static PolicyRuleConditionComparisonOperator valueOf(int value) {
+    public static NumericalOperator valueOf(int value) {
       return forNumber(value);
     }
 
@@ -146,27 +162,28 @@ public final class PolicyCondition {
      * @param value The numeric wire value of the corresponding enum entry.
      * @return The enum associated with the given numeric wire value.
      */
-    public static PolicyRuleConditionComparisonOperator forNumber(int value) {
+    public static NumericalOperator forNumber(int value) {
       switch (value) {
-        case 0: return EQUAL;
-        case 1: return NOT_EQUAL;
-        case 2: return LESS_THAN;
-        case 3: return LESS_THAN_EQUAL;
-        case 4: return GREATER_THAN;
-        case 5: return GREATER_THAN_EQUAL;
+        case 0: return POLICYRULE_CONDITION_NUMERICAL_UNDEFINED;
+        case 1: return POLICYRULE_CONDITION_NUMERICAL_EQUAL;
+        case 2: return POLICYRULE_CONDITION_NUMERICAL_NOT_EQUAL;
+        case 3: return POLICYRULE_CONDITION_NUMERICAL_LESS_THAN;
+        case 4: return POLICYRULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL;
+        case 5: return POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN;
+        case 6: return POLICYRULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL;
         default: return null;
       }
     }
 
-    public static com.google.protobuf.Internal.EnumLiteMap<PolicyRuleConditionComparisonOperator>
+    public static com.google.protobuf.Internal.EnumLiteMap<NumericalOperator>
         internalGetValueMap() {
       return internalValueMap;
     }
     private static final com.google.protobuf.Internal.EnumLiteMap<
-        PolicyRuleConditionComparisonOperator> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<PolicyRuleConditionComparisonOperator>() {
-            public PolicyRuleConditionComparisonOperator findValueByNumber(int number) {
-              return PolicyRuleConditionComparisonOperator.forNumber(number);
+        NumericalOperator> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<NumericalOperator>() {
+            public NumericalOperator findValueByNumber(int number) {
+              return NumericalOperator.forNumber(number);
             }
           };
 
@@ -187,9 +204,9 @@ public final class PolicyCondition {
       return policy.PolicyCondition.getDescriptor().getEnumTypes().get(0);
     }
 
-    private static final PolicyRuleConditionComparisonOperator[] VALUES = values();
+    private static final NumericalOperator[] VALUES = values();
 
-    public static PolicyRuleConditionComparisonOperator valueOf(
+    public static NumericalOperator valueOf(
         com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
       if (desc.getType() != getDescriptor()) {
         throw new java.lang.IllegalArgumentException(
@@ -203,11 +220,11 @@ public final class PolicyCondition {
 
     private final int value;
 
-    private PolicyRuleConditionComparisonOperator(int value) {
+    private NumericalOperator(int value) {
       this.value = value;
     }
 
-    // @@protoc_insertion_point(enum_scope:policy.PolicyRuleConditionComparisonOperator)
+    // @@protoc_insertion_point(enum_scope:policy.NumericalOperator)
   }
 
   /**
@@ -215,45 +232,61 @@ public final class PolicyCondition {
    * Operator to be used when evaluating each condition
    * </pre>
    *
-   * Protobuf enum {@code policy.PolicyRuleConditionEvaluationOperator}
+   * Protobuf enum {@code policy.BooleanOperator}
    */
-  public enum PolicyRuleConditionEvaluationOperator
+  public enum BooleanOperator
       implements com.google.protobuf.ProtocolMessageEnum {
     /**
      * <pre>
-     * Logical AND operator
+     * Boolean operator undefined
      * </pre>
      *
-     * <code>AND = 0;</code>
+     * <code>POLICYRULE_CONDITION_BOOLEAN_UNDEFINED = 0;</code>
      */
-    AND(0),
+    POLICYRULE_CONDITION_BOOLEAN_UNDEFINED(0),
     /**
      * <pre>
-     * Logical OR operator
+     * Boolean AND operator
      * </pre>
      *
-     * <code>OR = 1;</code>
+     * <code>POLICYRULE_CONDITION_BOOLEAN_AND = 1;</code>
      */
-    OR(1),
+    POLICYRULE_CONDITION_BOOLEAN_AND(1),
+    /**
+     * <pre>
+     * Boolean OR operator
+     * </pre>
+     *
+     * <code>POLICYRULE_CONDITION_BOOLEAN_OR = 2;</code>
+     */
+    POLICYRULE_CONDITION_BOOLEAN_OR(2),
     UNRECOGNIZED(-1),
     ;
 
     /**
      * <pre>
-     * Logical AND operator
+     * Boolean operator undefined
+     * </pre>
+     *
+     * <code>POLICYRULE_CONDITION_BOOLEAN_UNDEFINED = 0;</code>
+     */
+    public static final int POLICYRULE_CONDITION_BOOLEAN_UNDEFINED_VALUE = 0;
+    /**
+     * <pre>
+     * Boolean AND operator
      * </pre>
      *
-     * <code>AND = 0;</code>
+     * <code>POLICYRULE_CONDITION_BOOLEAN_AND = 1;</code>
      */
-    public static final int AND_VALUE = 0;
+    public static final int POLICYRULE_CONDITION_BOOLEAN_AND_VALUE = 1;
     /**
      * <pre>
-     * Logical OR operator
+     * Boolean OR operator
      * </pre>
      *
-     * <code>OR = 1;</code>
+     * <code>POLICYRULE_CONDITION_BOOLEAN_OR = 2;</code>
      */
-    public static final int OR_VALUE = 1;
+    public static final int POLICYRULE_CONDITION_BOOLEAN_OR_VALUE = 2;
 
 
     public final int getNumber() {
@@ -270,7 +303,7 @@ public final class PolicyCondition {
      * @deprecated Use {@link #forNumber(int)} instead.
      */
     @java.lang.Deprecated
-    public static PolicyRuleConditionEvaluationOperator valueOf(int value) {
+    public static BooleanOperator valueOf(int value) {
       return forNumber(value);
     }
 
@@ -278,23 +311,24 @@ public final class PolicyCondition {
      * @param value The numeric wire value of the corresponding enum entry.
      * @return The enum associated with the given numeric wire value.
      */
-    public static PolicyRuleConditionEvaluationOperator forNumber(int value) {
+    public static BooleanOperator forNumber(int value) {
       switch (value) {
-        case 0: return AND;
-        case 1: return OR;
+        case 0: return POLICYRULE_CONDITION_BOOLEAN_UNDEFINED;
+        case 1: return POLICYRULE_CONDITION_BOOLEAN_AND;
+        case 2: return POLICYRULE_CONDITION_BOOLEAN_OR;
         default: return null;
       }
     }
 
-    public static com.google.protobuf.Internal.EnumLiteMap<PolicyRuleConditionEvaluationOperator>
+    public static com.google.protobuf.Internal.EnumLiteMap<BooleanOperator>
         internalGetValueMap() {
       return internalValueMap;
     }
     private static final com.google.protobuf.Internal.EnumLiteMap<
-        PolicyRuleConditionEvaluationOperator> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<PolicyRuleConditionEvaluationOperator>() {
-            public PolicyRuleConditionEvaluationOperator findValueByNumber(int number) {
-              return PolicyRuleConditionEvaluationOperator.forNumber(number);
+        BooleanOperator> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<BooleanOperator>() {
+            public BooleanOperator findValueByNumber(int number) {
+              return BooleanOperator.forNumber(number);
             }
           };
 
@@ -315,9 +349,9 @@ public final class PolicyCondition {
       return policy.PolicyCondition.getDescriptor().getEnumTypes().get(1);
     }
 
-    private static final PolicyRuleConditionEvaluationOperator[] VALUES = values();
+    private static final BooleanOperator[] VALUES = values();
 
-    public static PolicyRuleConditionEvaluationOperator valueOf(
+    public static BooleanOperator valueOf(
         com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
       if (desc.getType() != getDescriptor()) {
         throw new java.lang.IllegalArgumentException(
@@ -331,11 +365,11 @@ public final class PolicyCondition {
 
     private final int value;
 
-    private PolicyRuleConditionEvaluationOperator(int value) {
+    private BooleanOperator(int value) {
       this.value = value;
     }
 
-    // @@protoc_insertion_point(enum_scope:policy.PolicyRuleConditionEvaluationOperator)
+    // @@protoc_insertion_point(enum_scope:policy.BooleanOperator)
   }
 
   public interface PolicyRuleConditionOrBuilder extends
@@ -358,15 +392,15 @@ public final class PolicyCondition {
     monitoring.Monitoring.KpiIdOrBuilder getKpiIdOrBuilder();
 
     /**
-     * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
-     * @return The enum numeric value on the wire for polRuleConditionComparisonOperator.
+     * <code>.policy.NumericalOperator numericalOperator = 2;</code>
+     * @return The enum numeric value on the wire for numericalOperator.
      */
-    int getPolRuleConditionComparisonOperatorValue();
+    int getNumericalOperatorValue();
     /**
-     * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
-     * @return The polRuleConditionComparisonOperator.
+     * <code>.policy.NumericalOperator numericalOperator = 2;</code>
+     * @return The numericalOperator.
      */
-    policy.PolicyCondition.PolicyRuleConditionComparisonOperator getPolRuleConditionComparisonOperator();
+    policy.PolicyCondition.NumericalOperator getNumericalOperator();
 
     /**
      * <code>.monitoring.KpiValue kpiValue = 3;</code>
@@ -400,7 +434,7 @@ public final class PolicyCondition {
       super(builder);
     }
     private PolicyRuleCondition() {
-      polRuleConditionComparisonOperator_ = 0;
+      numericalOperator_ = 0;
     }
 
     @java.lang.Override
@@ -449,7 +483,7 @@ public final class PolicyCondition {
             case 16: {
               int rawValue = input.readEnum();
 
-              polRuleConditionComparisonOperator_ = rawValue;
+              numericalOperator_ = rawValue;
               break;
             }
             case 26: {
@@ -523,23 +557,23 @@ public final class PolicyCondition {
       return getKpiId();
     }
 
-    public static final int POLRULECONDITIONCOMPARISONOPERATOR_FIELD_NUMBER = 2;
-    private int polRuleConditionComparisonOperator_;
+    public static final int NUMERICALOPERATOR_FIELD_NUMBER = 2;
+    private int numericalOperator_;
     /**
-     * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
-     * @return The enum numeric value on the wire for polRuleConditionComparisonOperator.
+     * <code>.policy.NumericalOperator numericalOperator = 2;</code>
+     * @return The enum numeric value on the wire for numericalOperator.
      */
-    @java.lang.Override public int getPolRuleConditionComparisonOperatorValue() {
-      return polRuleConditionComparisonOperator_;
+    @java.lang.Override public int getNumericalOperatorValue() {
+      return numericalOperator_;
     }
     /**
-     * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
-     * @return The polRuleConditionComparisonOperator.
+     * <code>.policy.NumericalOperator numericalOperator = 2;</code>
+     * @return The numericalOperator.
      */
-    @java.lang.Override public policy.PolicyCondition.PolicyRuleConditionComparisonOperator getPolRuleConditionComparisonOperator() {
+    @java.lang.Override public policy.PolicyCondition.NumericalOperator getNumericalOperator() {
       @SuppressWarnings("deprecation")
-      policy.PolicyCondition.PolicyRuleConditionComparisonOperator result = policy.PolicyCondition.PolicyRuleConditionComparisonOperator.valueOf(polRuleConditionComparisonOperator_);
-      return result == null ? policy.PolicyCondition.PolicyRuleConditionComparisonOperator.UNRECOGNIZED : result;
+      policy.PolicyCondition.NumericalOperator result = policy.PolicyCondition.NumericalOperator.valueOf(numericalOperator_);
+      return result == null ? policy.PolicyCondition.NumericalOperator.UNRECOGNIZED : result;
     }
 
     public static final int KPIVALUE_FIELD_NUMBER = 3;
@@ -585,8 +619,8 @@ public final class PolicyCondition {
       if (kpiId_ != null) {
         output.writeMessage(1, getKpiId());
       }
-      if (polRuleConditionComparisonOperator_ != policy.PolicyCondition.PolicyRuleConditionComparisonOperator.EQUAL.getNumber()) {
-        output.writeEnum(2, polRuleConditionComparisonOperator_);
+      if (numericalOperator_ != policy.PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_UNDEFINED.getNumber()) {
+        output.writeEnum(2, numericalOperator_);
       }
       if (kpiValue_ != null) {
         output.writeMessage(3, getKpiValue());
@@ -604,9 +638,9 @@ public final class PolicyCondition {
         size += com.google.protobuf.CodedOutputStream
           .computeMessageSize(1, getKpiId());
       }
-      if (polRuleConditionComparisonOperator_ != policy.PolicyCondition.PolicyRuleConditionComparisonOperator.EQUAL.getNumber()) {
+      if (numericalOperator_ != policy.PolicyCondition.NumericalOperator.POLICYRULE_CONDITION_NUMERICAL_UNDEFINED.getNumber()) {
         size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(2, polRuleConditionComparisonOperator_);
+          .computeEnumSize(2, numericalOperator_);
       }
       if (kpiValue_ != null) {
         size += com.google.protobuf.CodedOutputStream
@@ -632,7 +666,7 @@ public final class PolicyCondition {
         if (!getKpiId()
             .equals(other.getKpiId())) return false;
       }
-      if (polRuleConditionComparisonOperator_ != other.polRuleConditionComparisonOperator_) return false;
+      if (numericalOperator_ != other.numericalOperator_) return false;
       if (hasKpiValue() != other.hasKpiValue()) return false;
       if (hasKpiValue()) {
         if (!getKpiValue()
@@ -653,8 +687,8 @@ public final class PolicyCondition {
         hash = (37 * hash) + KPIID_FIELD_NUMBER;
         hash = (53 * hash) + getKpiId().hashCode();
       }
-      hash = (37 * hash) + POLRULECONDITIONCOMPARISONOPERATOR_FIELD_NUMBER;
-      hash = (53 * hash) + polRuleConditionComparisonOperator_;
+      hash = (37 * hash) + NUMERICALOPERATOR_FIELD_NUMBER;
+      hash = (53 * hash) + numericalOperator_;
       if (hasKpiValue()) {
         hash = (37 * hash) + KPIVALUE_FIELD_NUMBER;
         hash = (53 * hash) + getKpiValue().hashCode();
@@ -802,7 +836,7 @@ public final class PolicyCondition {
           kpiId_ = null;
           kpiIdBuilder_ = null;
         }
-        polRuleConditionComparisonOperator_ = 0;
+        numericalOperator_ = 0;
 
         if (kpiValueBuilder_ == null) {
           kpiValue_ = null;
@@ -841,7 +875,7 @@ public final class PolicyCondition {
         } else {
           result.kpiId_ = kpiIdBuilder_.build();
         }
-        result.polRuleConditionComparisonOperator_ = polRuleConditionComparisonOperator_;
+        result.numericalOperator_ = numericalOperator_;
         if (kpiValueBuilder_ == null) {
           result.kpiValue_ = kpiValue_;
         } else {
@@ -898,8 +932,8 @@ public final class PolicyCondition {
         if (other.hasKpiId()) {
           mergeKpiId(other.getKpiId());
         }
-        if (other.polRuleConditionComparisonOperator_ != 0) {
-          setPolRuleConditionComparisonOperatorValue(other.getPolRuleConditionComparisonOperatorValue());
+        if (other.numericalOperator_ != 0) {
+          setNumericalOperatorValue(other.getNumericalOperatorValue());
         }
         if (other.hasKpiValue()) {
           mergeKpiValue(other.getKpiValue());
@@ -1052,56 +1086,56 @@ public final class PolicyCondition {
         return kpiIdBuilder_;
       }
 
-      private int polRuleConditionComparisonOperator_ = 0;
+      private int numericalOperator_ = 0;
       /**
-       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
-       * @return The enum numeric value on the wire for polRuleConditionComparisonOperator.
+       * <code>.policy.NumericalOperator numericalOperator = 2;</code>
+       * @return The enum numeric value on the wire for numericalOperator.
        */
-      @java.lang.Override public int getPolRuleConditionComparisonOperatorValue() {
-        return polRuleConditionComparisonOperator_;
+      @java.lang.Override public int getNumericalOperatorValue() {
+        return numericalOperator_;
       }
       /**
-       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
-       * @param value The enum numeric value on the wire for polRuleConditionComparisonOperator to set.
+       * <code>.policy.NumericalOperator numericalOperator = 2;</code>
+       * @param value The enum numeric value on the wire for numericalOperator to set.
        * @return This builder for chaining.
        */
-      public Builder setPolRuleConditionComparisonOperatorValue(int value) {
+      public Builder setNumericalOperatorValue(int value) {
         
-        polRuleConditionComparisonOperator_ = value;
+        numericalOperator_ = value;
         onChanged();
         return this;
       }
       /**
-       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
-       * @return The polRuleConditionComparisonOperator.
+       * <code>.policy.NumericalOperator numericalOperator = 2;</code>
+       * @return The numericalOperator.
        */
       @java.lang.Override
-      public policy.PolicyCondition.PolicyRuleConditionComparisonOperator getPolRuleConditionComparisonOperator() {
+      public policy.PolicyCondition.NumericalOperator getNumericalOperator() {
         @SuppressWarnings("deprecation")
-        policy.PolicyCondition.PolicyRuleConditionComparisonOperator result = policy.PolicyCondition.PolicyRuleConditionComparisonOperator.valueOf(polRuleConditionComparisonOperator_);
-        return result == null ? policy.PolicyCondition.PolicyRuleConditionComparisonOperator.UNRECOGNIZED : result;
+        policy.PolicyCondition.NumericalOperator result = policy.PolicyCondition.NumericalOperator.valueOf(numericalOperator_);
+        return result == null ? policy.PolicyCondition.NumericalOperator.UNRECOGNIZED : result;
       }
       /**
-       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
-       * @param value The polRuleConditionComparisonOperator to set.
+       * <code>.policy.NumericalOperator numericalOperator = 2;</code>
+       * @param value The numericalOperator to set.
        * @return This builder for chaining.
        */
-      public Builder setPolRuleConditionComparisonOperator(policy.PolicyCondition.PolicyRuleConditionComparisonOperator value) {
+      public Builder setNumericalOperator(policy.PolicyCondition.NumericalOperator value) {
         if (value == null) {
           throw new NullPointerException();
         }
         
-        polRuleConditionComparisonOperator_ = value.getNumber();
+        numericalOperator_ = value.getNumber();
         onChanged();
         return this;
       }
       /**
-       * <code>.policy.PolicyRuleConditionComparisonOperator polRuleConditionComparisonOperator = 2;</code>
+       * <code>.policy.NumericalOperator numericalOperator = 2;</code>
        * @return This builder for chaining.
        */
-      public Builder clearPolRuleConditionComparisonOperator() {
+      public Builder clearNumericalOperator() {
         
-        polRuleConditionComparisonOperator_ = 0;
+        numericalOperator_ = 0;
         onChanged();
         return this;
       }
@@ -1292,17 +1326,23 @@ public final class PolicyCondition {
   static {
     java.lang.String[] descriptorData = {
       "\n\026policy-condition.proto\022\006policy\032\020monito" +
-      "ring.proto\"\272\001\n\023PolicyRuleCondition\022 \n\005kp" +
-      "iId\030\001 \001(\0132\021.monitoring.KpiId\022Y\n\"polRuleC" +
-      "onditionComparisonOperator\030\002 \001(\0162-.polic" +
-      "y.PolicyRuleConditionComparisonOperator\022" +
-      "&\n\010kpiValue\030\003 \001(\0132\024.monitoring.KpiValue*" +
-      "\217\001\n%PolicyRuleConditionComparisonOperato" +
-      "r\022\t\n\005EQUAL\020\000\022\r\n\tNOT_EQUAL\020\001\022\r\n\tLESS_THAN" +
-      "\020\002\022\023\n\017LESS_THAN_EQUAL\020\003\022\020\n\014GREATER_THAN\020" +
-      "\004\022\026\n\022GREATER_THAN_EQUAL\020\005*8\n%PolicyRuleC" +
-      "onditionEvaluationOperator\022\007\n\003AND\020\000\022\006\n\002O" +
-      "R\020\001b\006proto3"
+      "ring.proto\"\225\001\n\023PolicyRuleCondition\022 \n\005kp" +
+      "iId\030\001 \001(\0132\021.monitoring.KpiId\0224\n\021numerica" +
+      "lOperator\030\002 \001(\0162\031.policy.NumericalOperat" +
+      "or\022&\n\010kpiValue\030\003 \001(\0132\024.monitoring.KpiVal" +
+      "ue*\343\002\n\021NumericalOperator\022,\n(POLICYRULE_C" +
+      "ONDITION_NUMERICAL_UNDEFINED\020\000\022(\n$POLICY" +
+      "RULE_CONDITION_NUMERICAL_EQUAL\020\001\022,\n(POLI" +
+      "CYRULE_CONDITION_NUMERICAL_NOT_EQUAL\020\002\022," +
+      "\n(POLICYRULE_CONDITION_NUMERICAL_LESS_TH" +
+      "AN\020\003\0222\n.POLICYRULE_CONDITION_NUMERICAL_L" +
+      "ESS_THAN_EQUAL\020\004\022/\n+POLICYRULE_CONDITION" +
+      "_NUMERICAL_GREATER_THAN\020\005\0225\n1POLICYRULE_" +
+      "CONDITION_NUMERICAL_GREATER_THAN_EQUAL\020\006" +
+      "*\210\001\n\017BooleanOperator\022*\n&POLICYRULE_CONDI" +
+      "TION_BOOLEAN_UNDEFINED\020\000\022$\n POLICYRULE_C" +
+      "ONDITION_BOOLEAN_AND\020\001\022#\n\037POLICYRULE_CON" +
+      "DITION_BOOLEAN_OR\020\002b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -1314,7 +1354,7 @@ public final class PolicyCondition {
     internal_static_policy_PolicyRuleCondition_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_policy_PolicyRuleCondition_descriptor,
-        new java.lang.String[] { "KpiId", "PolRuleConditionComparisonOperator", "KpiValue", });
+        new java.lang.String[] { "KpiId", "NumericalOperator", "KpiValue", });
     monitoring.Monitoring.getDescriptor();
   }
 
-- 
GitLab


From ae963a03c93473d9aeec63c942a15e1e2e7d0ecd Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Tue, 31 May 2022 13:45:48 +0300
Subject: [PATCH 50/60] chore(policy): add service & monitoring proto files

---
 src/policy/src/main/proto/service.proto | 1 +
 1 file changed, 1 insertion(+)
 create mode 120000 src/policy/src/main/proto/service.proto

diff --git a/src/policy/src/main/proto/service.proto b/src/policy/src/main/proto/service.proto
new file mode 120000
index 000000000..5ca543da0
--- /dev/null
+++ b/src/policy/src/main/proto/service.proto
@@ -0,0 +1 @@
+../../../../../proto/service.proto
\ No newline at end of file
-- 
GitLab


From 7596ecf3c12fb7e5baa5a971ec8ccc359923bb2a Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Tue, 31 May 2022 16:03:47 +0300
Subject: [PATCH 51/60] feat(policy): add monitoring related domain models

---
 .../kpi_sample_types/model/KpiSampleType.java | 25 +++++++
 .../monitoring/model/BooleanKpiValue.java     | 20 +++++
 .../monitoring/model/FloatKpiValue.java       | 20 +++++
 .../monitoring/model/IntegerKpiValue.java     | 20 +++++
 .../teraflow/policy/monitoring/model/Kpi.java | 49 ++++++++++++
 .../monitoring/model/KpiDescriptor.java       | 75 +++++++++++++++++++
 .../policy/monitoring/model/KpiValue.java     |  6 ++
 .../monitoring/model/StringKpiValue.java      | 20 +++++
 8 files changed, 235 insertions(+)
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/kpi_sample_types/model/KpiSampleType.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/monitoring/model/BooleanKpiValue.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/monitoring/model/FloatKpiValue.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/monitoring/model/IntegerKpiValue.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/monitoring/model/Kpi.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/monitoring/model/KpiDescriptor.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/monitoring/model/KpiValue.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/monitoring/model/StringKpiValue.java

diff --git a/src/policy/src/main/java/eu/teraflow/policy/kpi_sample_types/model/KpiSampleType.java b/src/policy/src/main/java/eu/teraflow/policy/kpi_sample_types/model/KpiSampleType.java
new file mode 100644
index 000000000..1bedde352
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/kpi_sample_types/model/KpiSampleType.java
@@ -0,0 +1,25 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.kpi_sample_types.model;
+
+public enum KpiSampleType {
+    UNKNOWN,
+    PACKETS_TRANSMITTED,
+    PACKETS_RECEIVED,
+    BYTES_TRANSMITTED,
+    BYTES_RECEIVED
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/BooleanKpiValue.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/BooleanKpiValue.java
new file mode 100644
index 000000000..aa2fe96cd
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/BooleanKpiValue.java
@@ -0,0 +1,20 @@
+package eu.teraflow.policy.monitoring.model;
+
+public class BooleanKpiValue implements KpiValue<Boolean> {
+
+    private final boolean value;
+
+    public BooleanKpiValue(boolean value) {
+        this.value = value;
+    }
+
+    @Override
+    public Boolean getValue() {
+        return this.value;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s:{value:\"%b\"}", getClass().getSimpleName(), value);
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/FloatKpiValue.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/FloatKpiValue.java
new file mode 100644
index 000000000..d183c9c75
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/FloatKpiValue.java
@@ -0,0 +1,20 @@
+package eu.teraflow.policy.monitoring.model;
+
+public class FloatKpiValue implements KpiValue<Float> {
+
+    private final float value;
+
+    public FloatKpiValue(float value) {
+        this.value = value;
+    }
+
+    @Override
+    public Float getValue() {
+        return this.value;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s:{value:\"%f\"}", getClass().getSimpleName(), value);
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/IntegerKpiValue.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/IntegerKpiValue.java
new file mode 100644
index 000000000..b7048b188
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/IntegerKpiValue.java
@@ -0,0 +1,20 @@
+package eu.teraflow.policy.monitoring.model;
+
+public class IntegerKpiValue implements KpiValue<Integer> {
+
+    private final int value;
+
+    public IntegerKpiValue(int value) {
+        this.value = value;
+    }
+
+    @Override
+    public Integer getValue() {
+        return this.value;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s:{value:\"%d\"}", getClass().getSimpleName(), value);
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/Kpi.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/Kpi.java
new file mode 100644
index 000000000..4d84c29d4
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/Kpi.java
@@ -0,0 +1,49 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.monitoring.model;
+
+public class Kpi {
+
+    private final String kpiId;
+    private final String timestamp;
+    private final String kpiValue;
+
+    public Kpi(String kpiId, String timestamp, String kpiValue) {
+        this.kpiId = kpiId;
+        this.timestamp = timestamp;
+        this.kpiValue = kpiValue;
+    }
+
+    public String getKpiId() {
+        return kpiId;
+    }
+
+    public String getTimestamp() {
+        return timestamp;
+    }
+
+    public String getKpiValue() {
+        return kpiValue;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{kpiId:\"%s\", timeStamp:\"%s\", kpiValue:\"%s\"}",
+                getClass().getSimpleName(), kpiId, timestamp, kpiValue);
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/KpiDescriptor.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/KpiDescriptor.java
new file mode 100644
index 000000000..85e09ce2e
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/KpiDescriptor.java
@@ -0,0 +1,75 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.monitoring.model;
+
+import eu.teraflow.policy.context.model.EndPointId;
+import eu.teraflow.policy.context.model.ServiceId;
+import eu.teraflow.policy.kpi_sample_types.model.KpiSampleType;
+
+public class KpiDescriptor {
+
+    private final String kpiDescription;
+    private final KpiSampleType kpiSampleType;
+    private final String deviceId;
+    private final EndPointId endPointId;
+    private final ServiceId serviceId;
+
+    public KpiDescriptor(
+            String kpiDescription,
+            KpiSampleType kpiSampleType,
+            String deviceId,
+            EndPointId endPointId,
+            ServiceId serviceId) {
+        this.kpiDescription = kpiDescription;
+        this.kpiSampleType = kpiSampleType;
+        this.deviceId = deviceId;
+        this.endPointId = endPointId;
+        this.serviceId = serviceId;
+    }
+
+    public String getKpiDescription() {
+        return kpiDescription;
+    }
+
+    public KpiSampleType getKpiSampleType() {
+        return kpiSampleType;
+    }
+
+    public String getDeviceId() {
+        return deviceId;
+    }
+
+    public EndPointId getEndPointId() {
+        return endPointId;
+    }
+
+    public ServiceId getServiceId() {
+        return serviceId;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{kpiDescription:\"%s\", kpiSampleType:\"%s\", deviceId:\"%s\", %s, %s}",
+                getClass().getSimpleName(),
+                kpiDescription,
+                kpiSampleType.toString(),
+                deviceId,
+                endPointId,
+                serviceId);
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/KpiValue.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/KpiValue.java
new file mode 100644
index 000000000..4313c8269
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/KpiValue.java
@@ -0,0 +1,6 @@
+package eu.teraflow.policy.monitoring.model;
+
+public interface KpiValue<T> {
+
+    public T getValue();
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/StringKpiValue.java b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/StringKpiValue.java
new file mode 100644
index 000000000..fade27221
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/monitoring/model/StringKpiValue.java
@@ -0,0 +1,20 @@
+package eu.teraflow.policy.monitoring.model;
+
+public class StringKpiValue implements KpiValue<String> {
+
+    private final String value;
+
+    public StringKpiValue(String value) {
+        this.value = value;
+    }
+
+    @Override
+    public String getValue() {
+        return this.value;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s:{value:\"%s\"}", getClass().getSimpleName(), value);
+    }
+}
-- 
GitLab


From 10e7a33b9a0ee3fd9c60a16e552320d90ce5cd6b Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Tue, 31 May 2022 16:05:04 +0300
Subject: [PATCH 52/60] feat(policy): add context related domain models

---
 .../{Uuid.java => ConfigActionEnum.java}      |  15 +-
 .../policy/context/model/ConfigRule.java      |  49 ++
 .../policy/context/model/Constraint.java      |  43 ++
 .../policy/context/model/EndPointId.java      |  49 ++
 .../teraflow/policy/context/model/Event.java  |   7 +
 .../policy/context/model/Service.java         |  86 ++++
 .../policy/context/model/ServiceConfig.java   |  43 ++
 .../policy/context/model/ServiceId.java       |  20 +-
 .../policy/context/model/ServiceStatus.java   |  35 ++
 .../{DeviceId.java => ServiceStatusEnum.java} |  16 +-
 .../{ContextId.java => ServiceTypeEnum.java}  |  16 +-
 .../policy/context/model/TopologyId.java      |  43 ++
 .../service/MutinyServiceServiceGrpc.java     | 168 +++++++
 .../grpc/service/Service.java                 |  42 ++
 .../grpc/service/ServiceService.java          |  20 +
 .../grpc/service/ServiceServiceBean.java      |  43 ++
 .../grpc/service/ServiceServiceClient.java    |  36 ++
 .../grpc/service/ServiceServiceGrpc.java      | 423 ++++++++++++++++++
 18 files changed, 1114 insertions(+), 40 deletions(-)
 rename src/policy/src/main/java/eu/teraflow/policy/context/model/{Uuid.java => ConfigActionEnum.java} (81%)
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/context/model/ConfigRule.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/context/model/Constraint.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/context/model/EndPointId.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/context/model/Service.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceConfig.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceStatus.java
 rename src/policy/src/main/java/eu/teraflow/policy/context/model/{DeviceId.java => ServiceStatusEnum.java} (76%)
 rename src/policy/src/main/java/eu/teraflow/policy/context/model/{ContextId.java => ServiceTypeEnum.java} (76%)
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/context/model/TopologyId.java
 create mode 100644 src/policy/target/generated-sources/grpc/service/MutinyServiceServiceGrpc.java
 create mode 100644 src/policy/target/generated-sources/grpc/service/Service.java
 create mode 100644 src/policy/target/generated-sources/grpc/service/ServiceService.java
 create mode 100644 src/policy/target/generated-sources/grpc/service/ServiceServiceBean.java
 create mode 100644 src/policy/target/generated-sources/grpc/service/ServiceServiceClient.java
 create mode 100644 src/policy/target/generated-sources/grpc/service/ServiceServiceGrpc.java

diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/Uuid.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/ConfigActionEnum.java
similarity index 81%
rename from src/policy/src/main/java/eu/teraflow/policy/context/model/Uuid.java
rename to src/policy/src/main/java/eu/teraflow/policy/context/model/ConfigActionEnum.java
index 9a429f5ac..6cc8e8441 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/Uuid.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/ConfigActionEnum.java
@@ -16,15 +16,8 @@
 
 package eu.teraflow.policy.context.model;
 
-public class Uuid {
-
-    private String id;
-
-    public Uuid(String id) {
-        this.id = id;
-    }
-
-    public String getId() {
-        return id;
-    }
+public enum ConfigActionEnum {
+    UNDEFINED,
+    SET,
+    DELETE
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/ConfigRule.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/ConfigRule.java
new file mode 100644
index 000000000..906acf1a3
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/ConfigRule.java
@@ -0,0 +1,49 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.context.model;
+
+public class ConfigRule {
+
+    private final ConfigActionEnum action;
+    private final String resourceKey;
+    private final String resourceValue;
+
+    public ConfigRule(ConfigActionEnum action, String resourceKey, String resourceValue) {
+        this.action = action;
+        this.resourceKey = resourceKey;
+        this.resourceValue = resourceValue;
+    }
+
+    public ConfigActionEnum getAction() {
+        return action;
+    }
+
+    public String getResourceKey() {
+        return resourceKey;
+    }
+
+    public String getResourceValue() {
+        return resourceValue;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{action:\"%s\", resourceKey:\"%s\", resourceValue:\"%s\"}",
+                getClass().getSimpleName(), action.toString(), resourceKey, resourceValue);
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/Constraint.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/Constraint.java
new file mode 100644
index 000000000..edc5c0df7
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/Constraint.java
@@ -0,0 +1,43 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.context.model;
+
+public class Constraint {
+
+    private final String constraintType;
+    private final String constraintValue;
+
+    public Constraint(String constraintType, String constraintValue) {
+        this.constraintType = constraintType;
+        this.constraintValue = constraintValue;
+    }
+
+    public String getConstraintType() {
+        return constraintType;
+    }
+
+    public String getConstraintValue() {
+        return constraintValue;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{constraintType:\"%s\", constraintValue:\"%s\"}",
+                getClass().getSimpleName(), constraintType, constraintValue);
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/EndPointId.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/EndPointId.java
new file mode 100644
index 000000000..e9a3cbeb0
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/EndPointId.java
@@ -0,0 +1,49 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.context.model;
+
+public class EndPointId {
+
+    private final TopologyId topologyId;
+    private final String deviceId;
+    private final String id;
+
+    public EndPointId(TopologyId topologyId, String deviceId, String id) {
+        this.topologyId = topologyId;
+        this.deviceId = deviceId;
+        this.id = id;
+    }
+
+    public TopologyId getTopologyId() {
+        return topologyId;
+    }
+
+    public String getDeviceId() {
+        return deviceId;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{%s, deviceId:\"%s\", id:\"%s\"}",
+                getClass().getSimpleName(), topologyId, deviceId, id);
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/Event.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/Event.java
index a9d532e06..67da36b5c 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/Event.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/Event.java
@@ -33,4 +33,11 @@ public class Event {
     public EventTypeEnum getEventTypeEnum() {
         return eventType;
     }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{timestamp:\"%f\", eventType:\"%s\"}",
+                getClass().getSimpleName(), timestamp, eventType.toString());
+    }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/Service.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/Service.java
new file mode 100644
index 000000000..5441a8cb0
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/Service.java
@@ -0,0 +1,86 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.context.model;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class Service {
+
+    private final ServiceId serviceId;
+    private final ServiceTypeEnum serviceType;
+    private final List<EndPointId> serviceEndPointIds;
+    private final List<Constraint> serviceConstraints;
+    private final ServiceStatus serviceStatus;
+    private final ServiceConfig serviceConfig;
+
+    public Service(
+            ServiceId serviceId,
+            ServiceTypeEnum serviceType,
+            List<EndPointId> serviceEndPointIds,
+            List<Constraint> serviceConstraints,
+            ServiceStatus serviceStatus,
+            ServiceConfig serviceConfig) {
+        this.serviceId = serviceId;
+        this.serviceType = serviceType;
+        this.serviceEndPointIds = serviceEndPointIds;
+        this.serviceConstraints = serviceConstraints;
+        this.serviceStatus = serviceStatus;
+        this.serviceConfig = serviceConfig;
+    }
+
+    public ServiceId getServiceId() {
+        return serviceId;
+    }
+
+    public ServiceTypeEnum getServiceType() {
+        return serviceType;
+    }
+
+    public List<EndPointId> getServiceEndPointIds() {
+        return serviceEndPointIds;
+    }
+
+    public List<Constraint> getServiceConstraints() {
+        return serviceConstraints;
+    }
+
+    public ServiceStatus getServiceStatus() {
+        return serviceStatus;
+    }
+
+    public ServiceConfig getServiceConfig() {
+        return serviceConfig;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{%s, serviceType:\"%s\", [%s], [%s], %s, %s}",
+                getClass().getSimpleName(),
+                serviceId,
+                serviceType.toString(),
+                toString(serviceEndPointIds),
+                toString(serviceConstraints),
+                serviceStatus,
+                serviceConfig);
+    }
+
+    private <T> String toString(List<T> list) {
+        return list.stream().map(T::toString).collect(Collectors.joining(", "));
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceConfig.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceConfig.java
new file mode 100644
index 000000000..22c8b3cb6
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceConfig.java
@@ -0,0 +1,43 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.context.model;
+
+import java.util.List;
+import java.util.stream.Collectors;
+
+public class ServiceConfig {
+
+    private final List<ConfigRule> configRules;
+
+    public ServiceConfig(List<ConfigRule> configRules) {
+        this.configRules = configRules;
+    }
+
+    public List<ConfigRule> getConfigRules() {
+        return configRules;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{configRules:[%s]}", getClass().getSimpleName(), toString(configRules));
+    }
+
+    private <T> String toString(List<T> list) {
+        return list.stream().map(T::toString).collect(Collectors.joining(", "));
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceId.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceId.java
index e8027d82c..6229c1de7 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceId.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceId.java
@@ -18,20 +18,26 @@ package eu.teraflow.policy.context.model;
 
 public class ServiceId {
 
-    private final ContextId contextId;
-    private final Uuid serviceUuid;
+    private final String contextId;
+    private final String id;
 
-    public ServiceId(ContextId contextId, Uuid serviceUuid) {
+    public ServiceId(String contextId, String id) {
 
         this.contextId = contextId;
-        this.serviceUuid = serviceUuid;
+        this.id = id;
     }
 
-    public ContextId getContextId() {
+    public String getContextId() {
         return contextId;
     }
 
-    public Uuid getServiceUuid() {
-        return serviceUuid;
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{contextId:\"%s\", id:\"%s\"}", getClass().getSimpleName(), contextId, id);
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceStatus.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceStatus.java
new file mode 100644
index 000000000..b5466d1f3
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceStatus.java
@@ -0,0 +1,35 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.context.model;
+
+public class ServiceStatus {
+
+    private final ServiceStatusEnum status;
+
+    public ServiceStatus(ServiceStatusEnum status) {
+        this.status = status;
+    }
+
+    public ServiceStatusEnum getServiceStatus() {
+        return status;
+    }
+
+    @Override
+    public String toString() {
+        return String.format("%s:{serviceStatus:\"%s\"}", getClass().getSimpleName(), status);
+    }
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceId.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceStatusEnum.java
similarity index 76%
rename from src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceId.java
rename to src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceStatusEnum.java
index 4277bf693..e39e2fa2c 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/DeviceId.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceStatusEnum.java
@@ -16,15 +16,9 @@
 
 package eu.teraflow.policy.context.model;
 
-public class DeviceId {
-
-    private final Uuid deviceId;
-
-    public DeviceId(Uuid deviceId) {
-        this.deviceId = deviceId;
-    }
-
-    public Uuid getDeviceId() {
-        return deviceId;
-    }
+public enum ServiceStatusEnum {
+    UNDEFINED,
+    PLANNED,
+    ACTIVE,
+    PENDING_REMOVAL
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/ContextId.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceTypeEnum.java
similarity index 76%
rename from src/policy/src/main/java/eu/teraflow/policy/context/model/ContextId.java
rename to src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceTypeEnum.java
index 47bcf543e..f13a408f9 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/context/model/ContextId.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/ServiceTypeEnum.java
@@ -16,15 +16,9 @@
 
 package eu.teraflow.policy.context.model;
 
-public class ContextId {
-
-    private final Uuid contextId;
-
-    public ContextId(Uuid contextId) {
-        this.contextId = contextId;
-    }
-
-    public Uuid getContextId() {
-        return contextId;
-    }
+public enum ServiceTypeEnum {
+    UNKNOWN,
+    L3NM,
+    L2NM,
+    TAPI_CONNECTIVITY_SERVICE
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/context/model/TopologyId.java b/src/policy/src/main/java/eu/teraflow/policy/context/model/TopologyId.java
new file mode 100644
index 000000000..95157ba8c
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/context/model/TopologyId.java
@@ -0,0 +1,43 @@
+/*
+* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+package eu.teraflow.policy.context.model;
+
+public class TopologyId {
+
+    private final String contextId;
+    private final String id;
+
+    public TopologyId(String contextId, String id) {
+
+        this.contextId = contextId;
+        this.id = id;
+    }
+
+    public String getContextId() {
+        return contextId;
+    }
+
+    public String getId() {
+        return id;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{contextId:\"%s\", id:\"%s\"}", getClass().getSimpleName(), contextId, id);
+    }
+}
diff --git a/src/policy/target/generated-sources/grpc/service/MutinyServiceServiceGrpc.java b/src/policy/target/generated-sources/grpc/service/MutinyServiceServiceGrpc.java
new file mode 100644
index 000000000..8caa9641d
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/service/MutinyServiceServiceGrpc.java
@@ -0,0 +1,168 @@
+package service;
+
+import static service.ServiceServiceGrpc.getServiceDescriptor;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+
+@javax.annotation.Generated(
+value = "by Mutiny Grpc generator",
+comments = "Source: service.proto")
+public final class MutinyServiceServiceGrpc implements io.quarkus.grpc.runtime.MutinyGrpc {
+    private MutinyServiceServiceGrpc() {}
+
+    public static MutinyServiceServiceStub newMutinyStub(io.grpc.Channel channel) {
+        return new MutinyServiceServiceStub(channel);
+    }
+
+    
+    public static final class MutinyServiceServiceStub extends io.grpc.stub.AbstractStub<MutinyServiceServiceStub> implements io.quarkus.grpc.runtime.MutinyStub {
+        private ServiceServiceGrpc.ServiceServiceStub delegateStub;
+
+        private MutinyServiceServiceStub(io.grpc.Channel channel) {
+            super(channel);
+            delegateStub = ServiceServiceGrpc.newStub(channel);
+        }
+
+        private MutinyServiceServiceStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+            super(channel, callOptions);
+            delegateStub = ServiceServiceGrpc.newStub(channel).build(channel, callOptions);
+        }
+
+        @Override
+        protected MutinyServiceServiceStub build(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+            return new MutinyServiceServiceStub(channel, callOptions);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> createService(context.ContextOuterClass.Service request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::createService);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> updateService(context.ContextOuterClass.Service request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::updateService);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteService(context.ContextOuterClass.ServiceId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::deleteService);
+        }
+
+    }
+
+    
+    public static abstract class ServiceServiceImplBase implements io.grpc.BindableService {
+
+        private String compression;
+        /**
+        * Set whether the server will try to use a compressed response.
+        *
+        * @param compression the compression, e.g {@code gzip}
+        */
+        public ServiceServiceImplBase withCompression(String compression) {
+        this.compression = compression;
+        return this;
+        }
+
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> createService(context.ContextOuterClass.Service request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> updateService(context.ContextOuterClass.Service request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteService(context.ContextOuterClass.ServiceId request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+            return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+                    .addMethod(
+                            service.ServiceServiceGrpc.getCreateServiceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Service,
+                                            context.ContextOuterClass.ServiceId>(
+                                            this, METHODID_CREATE_SERVICE, compression)))
+                    .addMethod(
+                            service.ServiceServiceGrpc.getUpdateServiceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.Service,
+                                            context.ContextOuterClass.ServiceId>(
+                                            this, METHODID_UPDATE_SERVICE, compression)))
+                    .addMethod(
+                            service.ServiceServiceGrpc.getDeleteServiceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            context.ContextOuterClass.ServiceId,
+                                            context.ContextOuterClass.Empty>(
+                                            this, METHODID_DELETE_SERVICE, compression)))
+                    .build();
+        }
+    }
+
+    private static final int METHODID_CREATE_SERVICE = 0;
+    private static final int METHODID_UPDATE_SERVICE = 1;
+    private static final int METHODID_DELETE_SERVICE = 2;
+
+    private static final class MethodHandlers<Req, Resp> implements
+            io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+            io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+            io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+            io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+        private final ServiceServiceImplBase serviceImpl;
+        private final int methodId;
+        private final String compression;
+
+        MethodHandlers(ServiceServiceImplBase serviceImpl, int methodId, String compression) {
+            this.serviceImpl = serviceImpl;
+            this.methodId = methodId;
+            this.compression = compression;
+        }
+
+        @java.lang.Override
+        @java.lang.SuppressWarnings("unchecked")
+        public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+            switch (methodId) {
+                case METHODID_CREATE_SERVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Service) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver,
+                            compression,
+                            serviceImpl::createService);
+                    break;
+                case METHODID_UPDATE_SERVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.Service) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver,
+                            compression,
+                            serviceImpl::updateService);
+                    break;
+                case METHODID_DELETE_SERVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ServiceId) request,
+                            (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver,
+                            compression,
+                            serviceImpl::deleteService);
+                    break;
+                default:
+                    throw new java.lang.AssertionError();
+            }
+        }
+
+        @java.lang.Override
+        @java.lang.SuppressWarnings("unchecked")
+        public io.grpc.stub.StreamObserver<Req> invoke(io.grpc.stub.StreamObserver<Resp> responseObserver) {
+            switch (methodId) {
+                default:
+                    throw new java.lang.AssertionError();
+            }
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/service/Service.java b/src/policy/target/generated-sources/grpc/service/Service.java
new file mode 100644
index 000000000..32393a237
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/service/Service.java
@@ -0,0 +1,42 @@
+// Generated by the protocol buffer compiler.  DO NOT EDIT!
+// source: service.proto
+
+package service;
+
+public final class Service {
+  private Service() {}
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistryLite registry) {
+  }
+
+  public static void registerAllExtensions(
+      com.google.protobuf.ExtensionRegistry registry) {
+    registerAllExtensions(
+        (com.google.protobuf.ExtensionRegistryLite) registry);
+  }
+
+  public static com.google.protobuf.Descriptors.FileDescriptor
+      getDescriptor() {
+    return descriptor;
+  }
+  private static  com.google.protobuf.Descriptors.FileDescriptor
+      descriptor;
+  static {
+    java.lang.String[] descriptorData = {
+      "\n\rservice.proto\022\007service\032\rcontext.proto2" +
+      "\271\001\n\016ServiceService\0227\n\rCreateService\022\020.co" +
+      "ntext.Service\032\022.context.ServiceId\"\000\0227\n\rU" +
+      "pdateService\022\020.context.Service\032\022.context" +
+      ".ServiceId\"\000\0225\n\rDeleteService\022\022.context." +
+      "ServiceId\032\016.context.Empty\"\000b\006proto3"
+    };
+    descriptor = com.google.protobuf.Descriptors.FileDescriptor
+      .internalBuildGeneratedFileFrom(descriptorData,
+        new com.google.protobuf.Descriptors.FileDescriptor[] {
+          context.ContextOuterClass.getDescriptor(),
+        });
+    context.ContextOuterClass.getDescriptor();
+  }
+
+  // @@protoc_insertion_point(outer_class_scope)
+}
diff --git a/src/policy/target/generated-sources/grpc/service/ServiceService.java b/src/policy/target/generated-sources/grpc/service/ServiceService.java
new file mode 100644
index 000000000..b51f23536
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/service/ServiceService.java
@@ -0,0 +1,20 @@
+package service;
+
+import io.quarkus.grpc.runtime.MutinyService;
+
+@javax.annotation.Generated(
+value = "by Mutiny Grpc generator",
+comments = "Source: service.proto")
+public interface ServiceService extends MutinyService {
+
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> createService(context.ContextOuterClass.Service request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> updateService(context.ContextOuterClass.Service request);
+    
+    io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteService(context.ContextOuterClass.ServiceId request);
+    
+    
+    
+
+}
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/service/ServiceServiceBean.java b/src/policy/target/generated-sources/grpc/service/ServiceServiceBean.java
new file mode 100644
index 000000000..a4c34aaa8
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/service/ServiceServiceBean.java
@@ -0,0 +1,43 @@
+package service;
+
+import io.grpc.BindableService;
+import io.quarkus.grpc.GrpcService;
+import io.quarkus.grpc.runtime.MutinyBean;
+
+@javax.annotation.Generated(
+value = "by Mutiny Grpc generator",
+comments = "Source: service.proto")
+public class ServiceServiceBean extends MutinyServiceServiceGrpc.ServiceServiceImplBase implements BindableService, MutinyBean {
+
+    private final ServiceService delegate;
+
+    ServiceServiceBean(@GrpcService ServiceService delegate) {
+       this.delegate = delegate;
+    }
+
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> createService(context.ContextOuterClass.Service request) {
+       try {
+         return delegate.createService(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> updateService(context.ContextOuterClass.Service request) {
+       try {
+         return delegate.updateService(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteService(context.ContextOuterClass.ServiceId request) {
+       try {
+         return delegate.deleteService(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+
+}
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/service/ServiceServiceClient.java b/src/policy/target/generated-sources/grpc/service/ServiceServiceClient.java
new file mode 100644
index 000000000..91522d477
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/service/ServiceServiceClient.java
@@ -0,0 +1,36 @@
+package service;
+
+import java.util.function.BiFunction;
+
+import io.quarkus.grpc.runtime.MutinyClient;
+
+@javax.annotation.Generated(
+value = "by Mutiny Grpc generator",
+comments = "Source: service.proto")
+public class ServiceServiceClient implements ServiceService, MutinyClient<MutinyServiceServiceGrpc.MutinyServiceServiceStub> {
+
+    private final MutinyServiceServiceGrpc.MutinyServiceServiceStub stub;
+
+    public ServiceServiceClient(String name, io.grpc.Channel channel, BiFunction<String, MutinyServiceServiceGrpc.MutinyServiceServiceStub, MutinyServiceServiceGrpc.MutinyServiceServiceStub> stubConfigurator) {
+       this.stub = stubConfigurator.apply(name,MutinyServiceServiceGrpc.newMutinyStub(channel));
+    }
+
+    @Override
+    public MutinyServiceServiceGrpc.MutinyServiceServiceStub getStub() {
+       return stub;
+    }
+
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> createService(context.ContextOuterClass.Service request) {
+       return stub.createService(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.ServiceId> updateService(context.ContextOuterClass.Service request) {
+       return stub.updateService(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<context.ContextOuterClass.Empty> deleteService(context.ContextOuterClass.ServiceId request) {
+       return stub.deleteService(request);
+    }
+
+}
\ No newline at end of file
diff --git a/src/policy/target/generated-sources/grpc/service/ServiceServiceGrpc.java b/src/policy/target/generated-sources/grpc/service/ServiceServiceGrpc.java
new file mode 100644
index 000000000..66419a93b
--- /dev/null
+++ b/src/policy/target/generated-sources/grpc/service/ServiceServiceGrpc.java
@@ -0,0 +1,423 @@
+package service;
+
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+
+/**
+ */
+@javax.annotation.Generated(
+    value = "by gRPC proto compiler (version 1.38.1)",
+    comments = "Source: service.proto")
+public final class ServiceServiceGrpc {
+
+  private ServiceServiceGrpc() {}
+
+  public static final String SERVICE_NAME = "service.ServiceService";
+
+  // Static method descriptors that strictly reflect the proto.
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Service,
+      context.ContextOuterClass.ServiceId> getCreateServiceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "CreateService",
+      requestType = context.ContextOuterClass.Service.class,
+      responseType = context.ContextOuterClass.ServiceId.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.Service,
+      context.ContextOuterClass.ServiceId> getCreateServiceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId> getCreateServiceMethod;
+    if ((getCreateServiceMethod = ServiceServiceGrpc.getCreateServiceMethod) == null) {
+      synchronized (ServiceServiceGrpc.class) {
+        if ((getCreateServiceMethod = ServiceServiceGrpc.getCreateServiceMethod) == null) {
+          ServiceServiceGrpc.getCreateServiceMethod = getCreateServiceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "CreateService"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Service.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.ServiceId.getDefaultInstance()))
+              .setSchemaDescriptor(new ServiceServiceMethodDescriptorSupplier("CreateService"))
+              .build();
+        }
+      }
+    }
+    return getCreateServiceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.Service,
+      context.ContextOuterClass.ServiceId> getUpdateServiceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "UpdateService",
+      requestType = context.ContextOuterClass.Service.class,
+      responseType = context.ContextOuterClass.ServiceId.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.Service,
+      context.ContextOuterClass.ServiceId> getUpdateServiceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId> getUpdateServiceMethod;
+    if ((getUpdateServiceMethod = ServiceServiceGrpc.getUpdateServiceMethod) == null) {
+      synchronized (ServiceServiceGrpc.class) {
+        if ((getUpdateServiceMethod = ServiceServiceGrpc.getUpdateServiceMethod) == null) {
+          ServiceServiceGrpc.getUpdateServiceMethod = getUpdateServiceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.Service, context.ContextOuterClass.ServiceId>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "UpdateService"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Service.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.ServiceId.getDefaultInstance()))
+              .setSchemaDescriptor(new ServiceServiceMethodDescriptorSupplier("UpdateService"))
+              .build();
+        }
+      }
+    }
+    return getUpdateServiceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId,
+      context.ContextOuterClass.Empty> getDeleteServiceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "DeleteService",
+      requestType = context.ContextOuterClass.ServiceId.class,
+      responseType = context.ContextOuterClass.Empty.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId,
+      context.ContextOuterClass.Empty> getDeleteServiceMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId, context.ContextOuterClass.Empty> getDeleteServiceMethod;
+    if ((getDeleteServiceMethod = ServiceServiceGrpc.getDeleteServiceMethod) == null) {
+      synchronized (ServiceServiceGrpc.class) {
+        if ((getDeleteServiceMethod = ServiceServiceGrpc.getDeleteServiceMethod) == null) {
+          ServiceServiceGrpc.getDeleteServiceMethod = getDeleteServiceMethod =
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.ServiceId, context.ContextOuterClass.Empty>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "DeleteService"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.ServiceId.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  context.ContextOuterClass.Empty.getDefaultInstance()))
+              .setSchemaDescriptor(new ServiceServiceMethodDescriptorSupplier("DeleteService"))
+              .build();
+        }
+      }
+    }
+    return getDeleteServiceMethod;
+  }
+
+  /**
+   * Creates a new async stub that supports all call types for the service
+   */
+  public static ServiceServiceStub newStub(io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<ServiceServiceStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<ServiceServiceStub>() {
+        @java.lang.Override
+        public ServiceServiceStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new ServiceServiceStub(channel, callOptions);
+        }
+      };
+    return ServiceServiceStub.newStub(factory, channel);
+  }
+
+  /**
+   * Creates a new blocking-style stub that supports unary and streaming output calls on the service
+   */
+  public static ServiceServiceBlockingStub newBlockingStub(
+      io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<ServiceServiceBlockingStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<ServiceServiceBlockingStub>() {
+        @java.lang.Override
+        public ServiceServiceBlockingStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new ServiceServiceBlockingStub(channel, callOptions);
+        }
+      };
+    return ServiceServiceBlockingStub.newStub(factory, channel);
+  }
+
+  /**
+   * Creates a new ListenableFuture-style stub that supports unary calls on the service
+   */
+  public static ServiceServiceFutureStub newFutureStub(
+      io.grpc.Channel channel) {
+    io.grpc.stub.AbstractStub.StubFactory<ServiceServiceFutureStub> factory =
+      new io.grpc.stub.AbstractStub.StubFactory<ServiceServiceFutureStub>() {
+        @java.lang.Override
+        public ServiceServiceFutureStub newStub(io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+          return new ServiceServiceFutureStub(channel, callOptions);
+        }
+      };
+    return ServiceServiceFutureStub.newStub(factory, channel);
+  }
+
+  /**
+   */
+  public static abstract class ServiceServiceImplBase implements io.grpc.BindableService {
+
+    /**
+     */
+    public void createService(context.ContextOuterClass.Service request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getCreateServiceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void updateService(context.ContextOuterClass.Service request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getUpdateServiceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void deleteService(context.ContextOuterClass.ServiceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getDeleteServiceMethod(), responseObserver);
+    }
+
+    @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
+      return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+          .addMethod(
+            getCreateServiceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Service,
+                context.ContextOuterClass.ServiceId>(
+                  this, METHODID_CREATE_SERVICE)))
+          .addMethod(
+            getUpdateServiceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.Service,
+                context.ContextOuterClass.ServiceId>(
+                  this, METHODID_UPDATE_SERVICE)))
+          .addMethod(
+            getDeleteServiceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                context.ContextOuterClass.ServiceId,
+                context.ContextOuterClass.Empty>(
+                  this, METHODID_DELETE_SERVICE)))
+          .build();
+    }
+  }
+
+  /**
+   */
+  public static final class ServiceServiceStub extends io.grpc.stub.AbstractAsyncStub<ServiceServiceStub> {
+    private ServiceServiceStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected ServiceServiceStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new ServiceServiceStub(channel, callOptions);
+    }
+
+    /**
+     */
+    public void createService(context.ContextOuterClass.Service request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getCreateServiceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void updateService(context.ContextOuterClass.Service request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getUpdateServiceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void deleteService(context.ContextOuterClass.ServiceId request,
+        io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getDeleteServiceMethod(), getCallOptions()), request, responseObserver);
+    }
+  }
+
+  /**
+   */
+  public static final class ServiceServiceBlockingStub extends io.grpc.stub.AbstractBlockingStub<ServiceServiceBlockingStub> {
+    private ServiceServiceBlockingStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected ServiceServiceBlockingStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new ServiceServiceBlockingStub(channel, callOptions);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.ServiceId createService(context.ContextOuterClass.Service request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getCreateServiceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.ServiceId updateService(context.ContextOuterClass.Service request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getUpdateServiceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public context.ContextOuterClass.Empty deleteService(context.ContextOuterClass.ServiceId request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getDeleteServiceMethod(), getCallOptions(), request);
+    }
+  }
+
+  /**
+   */
+  public static final class ServiceServiceFutureStub extends io.grpc.stub.AbstractFutureStub<ServiceServiceFutureStub> {
+    private ServiceServiceFutureStub(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      super(channel, callOptions);
+    }
+
+    @java.lang.Override
+    protected ServiceServiceFutureStub build(
+        io.grpc.Channel channel, io.grpc.CallOptions callOptions) {
+      return new ServiceServiceFutureStub(channel, callOptions);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.ServiceId> createService(
+        context.ContextOuterClass.Service request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getCreateServiceMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.ServiceId> updateService(
+        context.ContextOuterClass.Service request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getUpdateServiceMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<context.ContextOuterClass.Empty> deleteService(
+        context.ContextOuterClass.ServiceId request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getDeleteServiceMethod(), getCallOptions()), request);
+    }
+  }
+
+  private static final int METHODID_CREATE_SERVICE = 0;
+  private static final int METHODID_UPDATE_SERVICE = 1;
+  private static final int METHODID_DELETE_SERVICE = 2;
+
+  private static final class MethodHandlers<Req, Resp> implements
+      io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+      io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+    private final ServiceServiceImplBase serviceImpl;
+    private final int methodId;
+
+    MethodHandlers(ServiceServiceImplBase serviceImpl, int methodId) {
+      this.serviceImpl = serviceImpl;
+      this.methodId = methodId;
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        case METHODID_CREATE_SERVICE:
+          serviceImpl.createService((context.ContextOuterClass.Service) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver);
+          break;
+        case METHODID_UPDATE_SERVICE:
+          serviceImpl.updateService((context.ContextOuterClass.Service) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.ServiceId>) responseObserver);
+          break;
+        case METHODID_DELETE_SERVICE:
+          serviceImpl.deleteService((context.ContextOuterClass.ServiceId) request,
+              (io.grpc.stub.StreamObserver<context.ContextOuterClass.Empty>) responseObserver);
+          break;
+        default:
+          throw new AssertionError();
+      }
+    }
+
+    @java.lang.Override
+    @java.lang.SuppressWarnings("unchecked")
+    public io.grpc.stub.StreamObserver<Req> invoke(
+        io.grpc.stub.StreamObserver<Resp> responseObserver) {
+      switch (methodId) {
+        default:
+          throw new AssertionError();
+      }
+    }
+  }
+
+  private static abstract class ServiceServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoFileDescriptorSupplier, io.grpc.protobuf.ProtoServiceDescriptorSupplier {
+    ServiceServiceBaseDescriptorSupplier() {}
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.FileDescriptor getFileDescriptor() {
+      return service.Service.getDescriptor();
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.ServiceDescriptor getServiceDescriptor() {
+      return getFileDescriptor().findServiceByName("ServiceService");
+    }
+  }
+
+  private static final class ServiceServiceFileDescriptorSupplier
+      extends ServiceServiceBaseDescriptorSupplier {
+    ServiceServiceFileDescriptorSupplier() {}
+  }
+
+  private static final class ServiceServiceMethodDescriptorSupplier
+      extends ServiceServiceBaseDescriptorSupplier
+      implements io.grpc.protobuf.ProtoMethodDescriptorSupplier {
+    private final String methodName;
+
+    ServiceServiceMethodDescriptorSupplier(String methodName) {
+      this.methodName = methodName;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Descriptors.MethodDescriptor getMethodDescriptor() {
+      return getServiceDescriptor().findMethodByName(methodName);
+    }
+  }
+
+  private static volatile io.grpc.ServiceDescriptor serviceDescriptor;
+
+  public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+    io.grpc.ServiceDescriptor result = serviceDescriptor;
+    if (result == null) {
+      synchronized (ServiceServiceGrpc.class) {
+        result = serviceDescriptor;
+        if (result == null) {
+          serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
+              .setSchemaDescriptor(new ServiceServiceFileDescriptorSupplier())
+              .addMethod(getCreateServiceMethod())
+              .addMethod(getUpdateServiceMethod())
+              .addMethod(getDeleteServiceMethod())
+              .build();
+        }
+      }
+    }
+    return result;
+  }
+}
-- 
GitLab


From 8f66b5359db2c8d2e730e9ec38ac5c488ccf3aa9 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Tue, 31 May 2022 16:05:49 +0300
Subject: [PATCH 53/60] feat(policy): add policy related domain models

---
 .../policy/model/BooleanOperator.java         |  7 ++
 .../policy/model/NumericalOperator.java       | 11 +++
 .../eu/teraflow/policy/model/PolicyRule.java  | 86 ++++++++++++-------
 .../policy/model/PolicyRuleAction.java        | 32 +++++--
 .../policy/model/PolicyRuleActionEnum.java    |  8 ++
 .../policy/model/PolicyRuleCondition.java     | 33 ++++---
 .../policy/model/PolicyRuleEvent.java         |  5 ++
 .../teraflow/policy/model/PolicyRuleId.java   | 32 -------
 .../policy/model/PolicyRulePriority.java      | 30 -------
 .../policy/model/PolicyRuleState.java         | 15 ++--
 .../teraflow/policy/model/PolicyRuleType.java |  4 +-
 .../policy/model/PolicyRuleValue.java         | 30 -------
 .../policy/model/PolicyRuleVariable.java      | 30 -------
 13 files changed, 146 insertions(+), 177 deletions(-)
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/BooleanOperator.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/NumericalOperator.java
 create mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleActionEnum.java
 delete mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleId.java
 delete mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/PolicyRulePriority.java
 delete mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleValue.java
 delete mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleVariable.java

diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/BooleanOperator.java b/src/policy/src/main/java/eu/teraflow/policy/model/BooleanOperator.java
new file mode 100644
index 000000000..4de1743d0
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/BooleanOperator.java
@@ -0,0 +1,7 @@
+package eu.teraflow.policy.model;
+
+public enum BooleanOperator {
+    POLICYRULE_CONDITION_BOOLEAN_UNDEFINED,
+    POLICYRULE_CONDITION_BOOLEAN_AND,
+    POLICYRULE_CONDITION_BOOLEAN_OR
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/NumericalOperator.java b/src/policy/src/main/java/eu/teraflow/policy/model/NumericalOperator.java
new file mode 100644
index 000000000..ccd424a02
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/NumericalOperator.java
@@ -0,0 +1,11 @@
+package eu.teraflow.policy.model;
+
+public enum NumericalOperator {
+    POLICY_RULE_CONDITION_NUMERICAL_UNDEFINED,
+    POLICY_RULE_CONDITION_NUMERICAL_EQUAL,
+    POLICY_RULE_CONDITION_NUMERICAL_NOT_EQUAL,
+    POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN,
+    POLICY_RULE_CONDITION_NUMERICAL_LESS_THAN_EQUAL,
+    POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN,
+    POLICY_RULE_CONDITION_NUMERICAL_GREATER_THAN_EQUAL
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java
index 20f78eb81..18dbfa73d 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java
@@ -16,40 +16,44 @@
 
 package eu.teraflow.policy.model;
 
-import eu.teraflow.policy.context.model.ContextId;
 import eu.teraflow.policy.context.model.ServiceId;
+import java.util.List;
+import java.util.stream.Collectors;
 
 public class PolicyRule {
 
-    private final PolicyRuleId policyRuleId;
+    private final String policyRuleId;
     private final PolicyRuleType policyRuleType;
-    private final PolicyRulePriority policyRulePriority;
-    private final PolicyRuleEvent policyRuleEvent;
-    private final PolicyRuleCondition policyRuleCondition;
-    private final PolicyRuleAction policyRuleAction;
+    private final int priority;
+    private final PolicyRuleEvent event;
+    private final List<PolicyRuleCondition> policyRuleConditions;
+    private final BooleanOperator booleanOperator;
+    private final List<PolicyRuleAction> policyRuleActions;
     private final ServiceId serviceId;
-    private final ContextId contextId;
+    private final List<String> deviceIds;
 
     public PolicyRule(
-            PolicyRuleId policyRuleId,
+            String policyRuleId,
             PolicyRuleType policyRuleType,
-            PolicyRulePriority policyRulePriority,
-            PolicyRuleEvent policyRuleEvent,
-            PolicyRuleCondition policyRuleCondition,
-            PolicyRuleAction policyRuleAction,
+            int priority,
+            PolicyRuleEvent event,
+            List<PolicyRuleCondition> policyRuleConditions,
+            BooleanOperator booleanOperator,
+            List<PolicyRuleAction> policyRuleActions,
             ServiceId serviceId,
-            ContextId contextId) {
+            List<String> deviceIds) {
         this.policyRuleId = policyRuleId;
         this.policyRuleType = policyRuleType;
-        this.policyRulePriority = policyRulePriority;
-        this.policyRuleEvent = policyRuleEvent;
-        this.policyRuleCondition = policyRuleCondition;
-        this.policyRuleAction = policyRuleAction;
+        this.priority = priority;
+        this.event = event;
+        this.policyRuleConditions = policyRuleConditions;
+        this.booleanOperator = booleanOperator;
+        this.policyRuleActions = policyRuleActions;
         this.serviceId = serviceId;
-        this.contextId = contextId;
+        this.deviceIds = deviceIds;
     }
 
-    public PolicyRuleId getPolicyRuleId() {
+    public String getPolicyRuleId() {
         return policyRuleId;
     }
 
@@ -57,27 +61,51 @@ public class PolicyRule {
         return policyRuleType;
     }
 
-    public PolicyRulePriority getPolicyRulePriority() {
-        return policyRulePriority;
+    public int getPriority() {
+        return priority;
     }
 
-    public PolicyRuleEvent getPolicyRuleEvent() {
-        return policyRuleEvent;
+    public PolicyRuleEvent getEvent() {
+        return event;
     }
 
-    public PolicyRuleCondition getPolicyRuleCondition() {
-        return policyRuleCondition;
+    public List<PolicyRuleCondition> getPolicyRuleConditions() {
+        return policyRuleConditions;
     }
 
-    public PolicyRuleAction getPolicyRuleAction() {
-        return policyRuleAction;
+    public BooleanOperator getBooleanOperator() {
+        return booleanOperator;
+    }
+
+    public List<PolicyRuleAction> getPolicyRuleActions() {
+        return policyRuleActions;
     }
 
     public ServiceId getServiceId() {
         return serviceId;
     }
 
-    public ContextId getContextId() {
-        return contextId;
+    public List<String> getDeviceIds() {
+        return deviceIds;
+    }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{policyRuleId:\"%s\", policyRuleType:\"%s\", priority:%d, %s, [%s], booleanOperator:\"%s\", [%s], %s, [%s]}",
+                getClass().getSimpleName(),
+                policyRuleId,
+                policyRuleType.toString(),
+                priority,
+                event,
+                toString(policyRuleConditions),
+                booleanOperator.toString(),
+                toString(policyRuleActions),
+                serviceId,
+                toString(deviceIds));
+    }
+
+    private <T> String toString(List<T> list) {
+        return list.stream().map(T::toString).collect(Collectors.joining(", "));
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleAction.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleAction.java
index 8592262ae..baa19cb8d 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleAction.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleAction.java
@@ -16,22 +16,36 @@
 
 package eu.teraflow.policy.model;
 
+import java.util.List;
+import java.util.stream.Collectors;
+
 public class PolicyRuleAction {
 
-    private final PolicyRuleVariable policyRuleVariable;
-    private final PolicyRuleValue policyRuleValue;
+    private final PolicyRuleActionEnum policyRuleActionEnum;
+    private final List<String> parameters;
+
+    public PolicyRuleAction(PolicyRuleActionEnum policyRuleActionEnum, List<String> parameters) {
 
-    public PolicyRuleAction(PolicyRuleVariable policyRuleVariable, PolicyRuleValue policyRuleValue) {
+        this.policyRuleActionEnum = policyRuleActionEnum;
+        this.parameters = parameters;
+    }
+
+    public PolicyRuleActionEnum getPolicyRuleActionEnum() {
+        return policyRuleActionEnum;
+    }
 
-        this.policyRuleVariable = policyRuleVariable;
-        this.policyRuleValue = policyRuleValue;
+    public List<String> getPolicyRuleActionParameters() {
+        return parameters;
     }
 
-    public PolicyRuleVariable getPolicyRuleVariable() {
-        return policyRuleVariable;
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{policyRuleActionEnum:\"%s\", [%s]}",
+                getClass().getSimpleName(), policyRuleActionEnum.toString(), toString(parameters));
     }
 
-    public PolicyRuleValue getPolicyRuleValue() {
-        return policyRuleValue;
+    private <T> String toString(List<T> list) {
+        return list.stream().map(T::toString).collect(Collectors.joining(", "));
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleActionEnum.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleActionEnum.java
new file mode 100644
index 000000000..317daa029
--- /dev/null
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleActionEnum.java
@@ -0,0 +1,8 @@
+package eu.teraflow.policy.model;
+
+public enum PolicyRuleActionEnum {
+    POLICY_RULE_ACTION_NO_ACTION,
+    POLICY_RULE_ACTION_SET_DEVICE_STATUS,
+    POLICY_RULE_ACTION_ADD_SERVICE_CONFIGRULE,
+    POLICY_RULE_ACTION_ADD_SERVICE_CONSTRAINT
+}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java
index 22d65124c..714cc5582 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleCondition.java
@@ -16,23 +16,36 @@
 
 package eu.teraflow.policy.model;
 
+import eu.teraflow.policy.monitoring.model.KpiValue;
+
 public class PolicyRuleCondition {
 
-    private final PolicyRuleVariable policyRuleVariable;
-    private final PolicyRuleValue policyRuleValue;
+    private final String kpiId;
+    private final NumericalOperator numericalOperator;
+    private final KpiValue<?> kpiValue;
+
+    public PolicyRuleCondition(String kpiId, NumericalOperator numericalOperator, KpiValue kpiValue) {
+        this.kpiId = kpiId;
+        this.numericalOperator = numericalOperator;
+        this.kpiValue = kpiValue;
+    }
 
-    public PolicyRuleCondition(
-            PolicyRuleVariable policyRuleVariable, PolicyRuleValue policyRuleValue) {
+    public String getKpiId() {
+        return kpiId;
+    }
 
-        this.policyRuleVariable = policyRuleVariable;
-        this.policyRuleValue = policyRuleValue;
+    public NumericalOperator getNumericalOperator() {
+        return numericalOperator;
     }
 
-    public PolicyRuleVariable getPolicyRuleVariable() {
-        return policyRuleVariable;
+    public KpiValue getKpiValue() {
+        return kpiValue;
     }
 
-    public PolicyRuleValue getPolicyRuleValue() {
-        return policyRuleValue;
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{kpiId:\"%s\", numericalOperator:\"%s\", %s}",
+                getClass().getSimpleName(), kpiId, numericalOperator.toString(), kpiValue);
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java
index 476d19482..412c6c718 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java
@@ -29,4 +29,9 @@ public class PolicyRuleEvent {
     public Event getEvent() {
         return event;
     }
+
+    @Override
+    public String toString() {
+        return String.format("%s:{%s}", getClass().getSimpleName(), event);
+    }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleId.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleId.java
deleted file mode 100644
index cc95d9e5d..000000000
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleId.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
-* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package eu.teraflow.policy.model;
-
-import eu.teraflow.policy.context.model.Uuid;
-
-public class PolicyRuleId {
-
-    private final Uuid policyRuleId;
-
-    public PolicyRuleId(Uuid policyRuleId) {
-        this.policyRuleId = policyRuleId;
-    }
-
-    public Uuid getPolicyRuleId() {
-        return policyRuleId;
-    }
-}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRulePriority.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRulePriority.java
deleted file mode 100644
index c85bb9a36..000000000
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRulePriority.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package eu.teraflow.policy.model;
-
-public class PolicyRulePriority {
-
-    private final int policyRulePriority;
-
-    public PolicyRulePriority(int policyRulePriority) {
-        this.policyRulePriority = policyRulePriority;
-    }
-
-    public int getPolicyRulePriority() {
-        return policyRulePriority;
-    }
-}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleState.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleState.java
index 43b934030..38ee0a73b 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleState.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleState.java
@@ -16,23 +16,28 @@
 
 package eu.teraflow.policy.model;
 
-import eu.teraflow.policy.context.model.Uuid;
-
 public class PolicyRuleState {
 
-    private final Uuid policeRuleId;
+    private final String policeRuleId;
     private final RuleState ruleState;
 
-    public PolicyRuleState(Uuid policeRuleId, RuleState ruleState) {
+    public PolicyRuleState(String policeRuleId, RuleState ruleState) {
         this.policeRuleId = policeRuleId;
         this.ruleState = ruleState;
     }
 
-    public Uuid getPolicyRuleId() {
+    public String getPolicyRuleId() {
         return policeRuleId;
     }
 
     public RuleState getRuleState() {
         return ruleState;
     }
+
+    @Override
+    public String toString() {
+        return String.format(
+                "%s:{policeRuleId:\"%s\", ruleState:\"%s\"}",
+                getClass().getSimpleName(), policeRuleId, ruleState);
+    }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java
index 6becad243..321220176 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java
@@ -17,6 +17,6 @@
 package eu.teraflow.policy.model;
 
 public enum PolicyRuleType {
-    DEVICE,
-    NETWORK
+    POLICYTYPE_DEVICE,
+    POLICYTYPE_NETWORK
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleValue.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleValue.java
deleted file mode 100644
index 9a928c4a2..000000000
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleValue.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package eu.teraflow.policy.model;
-
-public class PolicyRuleValue {
-
-    private final String policyRuleValue;
-
-    public PolicyRuleValue(String policyRuleValue) {
-        this.policyRuleValue = policyRuleValue;
-    }
-
-    public String getPolicyRuleValue() {
-        return policyRuleValue;
-    }
-}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleVariable.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleVariable.java
deleted file mode 100644
index fa35d270a..000000000
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleVariable.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package eu.teraflow.policy.model;
-
-public class PolicyRuleVariable {
-
-    private final String policyRuleVariable;
-
-    public PolicyRuleVariable(String policyRuleVariable) {
-        this.policyRuleVariable = policyRuleVariable;
-    }
-
-    public String getPolicyRuleVariable() {
-        return policyRuleVariable;
-    }
-}
-- 
GitLab


From 7668bd09339ac190db98893f9c2cb37eb70c318f Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Mon, 4 Jul 2022 17:41:54 +0200
Subject: [PATCH 54/60] DLT component:

- Defined new dlt.proto file
---
 proto/dlt.proto | 95 ++++++++++++++++++++++++++++---------------------
 1 file changed, 54 insertions(+), 41 deletions(-)

diff --git a/proto/dlt.proto b/proto/dlt.proto
index 29a0db198..0d5d4fe27 100644
--- a/proto/dlt.proto
+++ b/proto/dlt.proto
@@ -12,72 +12,85 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-//Example of topology
 syntax = "proto3";
 package dlt;
 
 import "context.proto";
 
 service DltService {
-  rpc RecordToDlt ( DltRecord ) returns ( RecordStatus ) {}
-  rpc GetFromDlt ( DltRecordId ) returns ( DltRecord ) {}
-  rpc SubscribeToDlt ( DltRecordSubscription ) returns ( stream DltRecord ) {}
-  rpc GetDltStatus ( context.Empty ) returns ( DltStatus ) {}
+  rpc RecordToDlt   (DltRecord                 ) returns (       DltRecordStatus  ) {}
+  rpc GetFromDlt    (DltRecordId               ) returns (       DltRecord        ) {}
+  rpc SubscribeToDlt(DltRecordSubscription     ) returns (stream DltRecordEvent   ) {}
+  rpc GetDltStatus  (context.TeraFlowController) returns (       DltPeerStatus    ) {}  // NEC is checkig if it is possible
+  rpc GetDltPeers   (context.Empty             ) returns (       DltPeerStatusList) {}  // NEC is checkig if it is possible
 }
 
-message DltRecordSubscription {
-  DltRecordType type = 1;
-  DltRecordOperation operation = 2;
+enum DltRecordTypeEnum {
+  DLTRECORDTYPE_UNDEFINED = 0;
+  DLTRECORDTYPE_CONTEXT   = 1;
+  DLTRECORDTYPE_TOPOLOGY  = 2;
+  DLTRECORDTYPE_DEVICE    = 3;
+  DLTRECORDTYPE_LINK      = 4;
+  DLTRECORDTYPE_SERVICE   = 5;
+  DLTRECORDTYPE_SLICE     = 6;
 }
 
-enum DltRecordType {
-  UNKNOWN = 0;
-  SERVICE = 1;
-  DEVICE = 2;
-  SLICE = 3;
+enum DltRecordOperationEnum {
+  DLTRECORDOPERATION_UNDEFINED = 0;
+  DLTRECORDOPERATION_ADD       = 1;
+  DLTRECORDOPERATION_UPDATE    = 2;
+  DLTRECORDOPERATION_DELETE    = 3;
 }
 
-enum DltRecordOperation {
-  ADD = 0;
-  UPDATE = 1;
-  DELETE = 2;
+enum DltRecordStatusEnum {
+  DLTRECORDSTATUS_UNDEFINED = 0;
+  DLTRECORDSTATUS_SUCCEEDED = 1;
+  DLTRECORDSTATUS_FAILED    = 2;
 }
 
-message DltRecord {
-  DltRecordId id = 1;
-  DltRecordType type = 2;  
-  DltRecordOperation operation = 3;
-  string json = 4;
+enum DltStatusEnum {
+  DLTSTATUS_UNDEFINED    = 0;
+  DLTSTATUS_NOTAVAILABLE = 1;
+  DLTSTATUS_INITIALIZED  = 2;
+  DLTSTATUS_AVAILABLE    = 3;
+  DLTSTATUS_DEINIT       = 4;
 }
 
 message DltRecordId {
-  context.Uuid id = 1;
+  context.Uuid      domain_uuid = 1;          // unique identifier of domain owning the record
+  DltRecordTypeEnum type        = 2;          // type of record
+  context.Uuid      record_uuid = 3;          // unique identifier of the record within the domain context_uuid/topology_uuid
 }
 
-message RecordStatus {
-  DltRecordId id = 1;
-  DltRecordStatusEnum status = 2;
+message DltRecord {
+  DltRecordId        record_id = 1;           // record identifier
+  DltRecordOperation operation = 2;           // operation to be performed over the record
+  string             data_json = 3;           // record content: JSON-encoded record content
 }
 
-enum DltRecordStatusEnum {
-  REQUESTED = 0;
-  STORED = 1;
-  DISABLED = 2;
+message DltRecordSubscription {
+  // retrieved events should match both conditions
+  // TODO: consider adding a more sophisticated filtering
+  repeated DltRecordType      type      = 1;  // only receive subscriptions of the selected types, empty=all
+  repeated DltRecordOperation operation = 2;  // only receive subscriptions of the selected operations, empty=all
 }
 
-
-message DltStatus {
-  context.TeraFlowController ctl = 1;
-  DltStatusEnum status = 2;
+message DltRecordEvent {
+  context.Event event     = 1;                // common event data (timestamp & event_type)
+  DltRecordId   record_id = 2;                // record identifier associated with this event
 }
 
-enum DltStatusEnum {
-  NOT_AVAILABLE = 0;
-  INITIALIZED = 1;
-  AVAILABLE = 2;
-  DEINIT = 3;
+message DltRecordStatus {
+  DltRecordId         record_id     = 1;      // identifier of the associated record
+  DltRecordStatusEnum status        = 2;      // status of the record
+  string              error_message = 3;      // error message in case of failure, empty otherwise
 }
 
+message DltPeerStatus {
+  context.TeraFlowController controller = 1;  // Identifier of the TeraFlow controller instance
+  DltStatusEnum              status     = 2;  // Status of the TeraFlow controller instance
+}
 
-
-
+message DltPeerStatusList {
+  repeated DltPeerStatus peers = 1;           // List of peers and their status
+}
-- 
GitLab


From b11c117692a7ef8797642d8bb3e2f159ff75bc7d Mon Sep 17 00:00:00 2001
From: Konstantin Munichev <konstantin.munichev@neclab.eu>
Date: Tue, 5 Jul 2022 15:03:15 +0200
Subject: [PATCH 55/60] Subcribe for chaincode events

---
 src/dlt/config/ca.org1.example.com-cert.pem      | 16 ++++++++--------
 src/dlt/config/connection-org1.json              |  8 ++++----
 src/dlt/src/main/kotlin/Main.kt                  |  3 +--
 .../src/main/kotlin/fabric/FabricConnector.kt    | 12 ++++++++++++
 4 files changed, 25 insertions(+), 14 deletions(-)

diff --git a/src/dlt/config/ca.org1.example.com-cert.pem b/src/dlt/config/ca.org1.example.com-cert.pem
index 9c10b9790..5287a0f2b 100644
--- a/src/dlt/config/ca.org1.example.com-cert.pem
+++ b/src/dlt/config/ca.org1.example.com-cert.pem
@@ -1,14 +1,14 @@
 -----BEGIN CERTIFICATE-----
-MIICJjCCAc2gAwIBAgIULDVQiqifWHypuW50LhHXSJeeFG0wCgYIKoZIzj0EAwIw
+MIICJjCCAc2gAwIBAgIUWZ4l32loO9+FM0FYw61y3dUF5a0wCgYIKoZIzj0EAwIw
 cDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH
 EwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh
-Lm9yZzEuZXhhbXBsZS5jb20wHhcNMjExMTIzMTIzNzAwWhcNMzYxMTE5MTIzNzAw
+Lm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNzA1MDk0NDAwWhcNMzcwNzAxMDk0NDAw
 WjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV
 BAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT
-Y2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFNi
-ggnkzv5qQSkIAQ05Y9DUq4teNjbMTdqD0IwdQe+lcYI0wgkR9wpBn5fj2pN093+P
-l2crhgyNqZyAuqaylvCjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG
-AQH/AgEBMB0GA1UdDgQWBBS44tGlbJ5GIBwATL383Hw0vz8jHDAKBggqhkjOPQQD
-AgNHADBEAiAlkKikh7eG8lf0uI7NwBi0QrbnnY4vHf9ErceKwUhZWgIgS9Z9AzBc
-n9RAK3v/freT3Exs7b+MK13UeDdejRWS+RE=
+Y2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNPg
+yfDxHr4ZmFp3HB19f27vfc1YTKBnznLqIFwVad2Y+eXfni8DnTRNGgwdkG9uIK2L
+4Y9mwlKG/mTNx629G4GjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG
+AQH/AgEBMB0GA1UdDgQWBBSZlT6qe+DAGpEBXyMxzidqCkQ4PjAKBggqhkjOPQQD
+AgNHADBEAiAIG5jwBGddB9CwocmjAzFv8+e7+0bvNSwjrG229QogTgIgbTNoC33P
+mbR5ChlkUAW2t41hTOCSMIwLAlvEwpeCnAk=
 -----END CERTIFICATE-----
diff --git a/src/dlt/config/connection-org1.json b/src/dlt/config/connection-org1.json
index c28ac5711..320a20806 100644
--- a/src/dlt/config/connection-org1.json
+++ b/src/dlt/config/connection-org1.json
@@ -26,7 +26,7 @@
         "peer0.org1.example.com": {
             "url": "grpcs://s2:7051",
             "tlsCACerts": {
-                "pem": "-----BEGIN CERTIFICATE-----\nMIICJjCCAc2gAwIBAgIULDVQiqifWHypuW50LhHXSJeeFG0wCgYIKoZIzj0EAwIw\ncDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH\nEwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjExMTIzMTIzNzAwWhcNMzYxMTE5MTIzNzAw\nWjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV\nBAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT\nY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFNi\nggnkzv5qQSkIAQ05Y9DUq4teNjbMTdqD0IwdQe+lcYI0wgkR9wpBn5fj2pN093+P\nl2crhgyNqZyAuqaylvCjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEBMB0GA1UdDgQWBBS44tGlbJ5GIBwATL383Hw0vz8jHDAKBggqhkjOPQQD\nAgNHADBEAiAlkKikh7eG8lf0uI7NwBi0QrbnnY4vHf9ErceKwUhZWgIgS9Z9AzBc\nn9RAK3v/freT3Exs7b+MK13UeDdejRWS+RE=\n-----END CERTIFICATE-----\n"
+                "pem": "-----BEGIN CERTIFICATE-----\nMIICJjCCAc2gAwIBAgIUWZ4l32loO9+FM0FYw61y3dUF5a0wCgYIKoZIzj0EAwIw\ncDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH\nEwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNzA1MDk0NDAwWhcNMzcwNzAxMDk0NDAw\nWjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV\nBAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT\nY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNPg\nyfDxHr4ZmFp3HB19f27vfc1YTKBnznLqIFwVad2Y+eXfni8DnTRNGgwdkG9uIK2L\n4Y9mwlKG/mTNx629G4GjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEBMB0GA1UdDgQWBBSZlT6qe+DAGpEBXyMxzidqCkQ4PjAKBggqhkjOPQQD\nAgNHADBEAiAIG5jwBGddB9CwocmjAzFv8+e7+0bvNSwjrG229QogTgIgbTNoC33P\nmbR5ChlkUAW2t41hTOCSMIwLAlvEwpeCnAk=\n-----END CERTIFICATE-----\n"
             },
             "grpcOptions": {
                 "ssl-target-name-override": "peer0.org1.example.com",
@@ -36,7 +36,7 @@
         "peer0.org2.example.com": {
             "url": "grpcs://s2:9051",
             "tlsCACerts": {
-                "pem": "-----BEGIN CERTIFICATE-----\nMIICHzCCAcWgAwIBAgIUJiJ5815YVes2sG95oFzj0QWWBKswCgYIKoZIzj0EAwIw\nbDELMAkGA1UEBhMCVUsxEjAQBgNVBAgTCUhhbXBzaGlyZTEQMA4GA1UEBxMHSHVy\nc2xleTEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eub3Jn\nMi5leGFtcGxlLmNvbTAeFw0yMTExMjMxMjM3MDBaFw0zNjExMTkxMjM3MDBaMGwx\nCzAJBgNVBAYTAlVLMRIwEAYDVQQIEwlIYW1wc2hpcmUxEDAOBgNVBAcTB0h1cnNs\nZXkxGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2NhLm9yZzIu\nZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAATdQw+PQyT3Ql5M\nv/xvafYFhU5Jtl0CwYyrXTtRajpPnlPnNvXUqVMxmdSR+4m2WBYyBdZ8IhGaayb/\nrOro8Mpko0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAd\nBgNVHQ4EFgQUrsPP1HIS6O+JeWL2ct/ujkfP7dEwCgYIKoZIzj0EAwIDSAAwRQIh\nAMynA2Q/cbMXEHihnQdpdEz/83jGAokp7dKMHst02b3gAiA0XReJWdc0AUXZtbSq\nZG8mXOJeZu0Zro9DuQUEDPBfDQ==\n-----END CERTIFICATE-----\n"
+                "pem": "-----BEGIN CERTIFICATE-----\nMIICHzCCAcWgAwIBAgIUejv57h6dJkVIM2R1YnlqykkvG7gwCgYIKoZIzj0EAwIw\nbDELMAkGA1UEBhMCVUsxEjAQBgNVBAgTCUhhbXBzaGlyZTEQMA4GA1UEBxMHSHVy\nc2xleTEZMBcGA1UEChMQb3JnMi5leGFtcGxlLmNvbTEcMBoGA1UEAxMTY2Eub3Jn\nMi5leGFtcGxlLmNvbTAeFw0yMjA3MDUwOTQ0MDBaFw0zNzA3MDEwOTQ0MDBaMGwx\nCzAJBgNVBAYTAlVLMRIwEAYDVQQIEwlIYW1wc2hpcmUxEDAOBgNVBAcTB0h1cnNs\nZXkxGTAXBgNVBAoTEG9yZzIuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2NhLm9yZzIu\nZXhhbXBsZS5jb20wWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASFZqoisCIgZyMM\n8e0YBA+jxH/+Fc4Y4OkEl5uGRXGl9s0OemCdvhlX9K+esX2DVk1st1PMfTEj/six\n9XPpVqzNo0UwQzAOBgNVHQ8BAf8EBAMCAQYwEgYDVR0TAQH/BAgwBgEB/wIBATAd\nBgNVHQ4EFgQUPEyzGBlZEjguoJB16wAmoH2bAh8wCgYIKoZIzj0EAwIDSAAwRQIh\nAL6DAWgrqRtbYoQ0oYAr/2vze0JtQcXoqiQKlyvYkUBbAiB/uSHBk3NwjzI8t8iW\nzQzr5eNy5JwOO0SWwPEv4Ev9iQ==\n-----END CERTIFICATE-----\n"
             },
             "grpcOptions": {
                 "ssl-target-name-override": "peer0.org2.example.com",
@@ -50,7 +50,7 @@
             "caName": "ca-org1",
             "tlsCACerts": {
                 "pem": [
-                    "-----BEGIN CERTIFICATE-----\nMIICJjCCAc2gAwIBAgIULDVQiqifWHypuW50LhHXSJeeFG0wCgYIKoZIzj0EAwIw\ncDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH\nEwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjExMTIzMTIzNzAwWhcNMzYxMTE5MTIzNzAw\nWjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV\nBAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT\nY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFNi\nggnkzv5qQSkIAQ05Y9DUq4teNjbMTdqD0IwdQe+lcYI0wgkR9wpBn5fj2pN093+P\nl2crhgyNqZyAuqaylvCjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEBMB0GA1UdDgQWBBS44tGlbJ5GIBwATL383Hw0vz8jHDAKBggqhkjOPQQD\nAgNHADBEAiAlkKikh7eG8lf0uI7NwBi0QrbnnY4vHf9ErceKwUhZWgIgS9Z9AzBc\nn9RAK3v/freT3Exs7b+MK13UeDdejRWS+RE=\n-----END CERTIFICATE-----\n"
+                    "-----BEGIN CERTIFICATE-----\nMIICJjCCAc2gAwIBAgIUWZ4l32loO9+FM0FYw61y3dUF5a0wCgYIKoZIzj0EAwIw\ncDELMAkGA1UEBhMCVVMxFzAVBgNVBAgTDk5vcnRoIENhcm9saW5hMQ8wDQYDVQQH\nEwZEdXJoYW0xGTAXBgNVBAoTEG9yZzEuZXhhbXBsZS5jb20xHDAaBgNVBAMTE2Nh\nLm9yZzEuZXhhbXBsZS5jb20wHhcNMjIwNzA1MDk0NDAwWhcNMzcwNzAxMDk0NDAw\nWjBwMQswCQYDVQQGEwJVUzEXMBUGA1UECBMOTm9ydGggQ2Fyb2xpbmExDzANBgNV\nBAcTBkR1cmhhbTEZMBcGA1UEChMQb3JnMS5leGFtcGxlLmNvbTEcMBoGA1UEAxMT\nY2Eub3JnMS5leGFtcGxlLmNvbTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABNPg\nyfDxHr4ZmFp3HB19f27vfc1YTKBnznLqIFwVad2Y+eXfni8DnTRNGgwdkG9uIK2L\n4Y9mwlKG/mTNx629G4GjRTBDMA4GA1UdDwEB/wQEAwIBBjASBgNVHRMBAf8ECDAG\nAQH/AgEBMB0GA1UdDgQWBBSZlT6qe+DAGpEBXyMxzidqCkQ4PjAKBggqhkjOPQQD\nAgNHADBEAiAIG5jwBGddB9CwocmjAzFv8+e7+0bvNSwjrG229QogTgIgbTNoC33P\nmbR5ChlkUAW2t41hTOCSMIwLAlvEwpeCnAk=\n-----END CERTIFICATE-----\n"
                 ]
             },
             "httpOptions": {
@@ -62,7 +62,7 @@
         "orderer0.example.com": {
             "url": "grpcs://s2:7050",
             "tlsCACerts": {
-                "pem": "-----BEGIN CERTIFICATE-----\nMIICCzCCAbGgAwIBAgIUDr4RiMRC/q95iWAfWiZTLTdDoDUwCgYIKoZIzj0EAwIw\nYjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcg\nWW9yazEUMBIGA1UEChMLZXhhbXBsZS5jb20xFzAVBgNVBAMTDmNhLmV4YW1wbGUu\nY29tMB4XDTIxMTEyMzEyMzcwMFoXDTM2MTExOTEyMzcwMFowYjELMAkGA1UEBhMC\nVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcgWW9yazEUMBIGA1UE\nChMLZXhhbXBsZS5jb20xFzAVBgNVBAMTDmNhLmV4YW1wbGUuY29tMFkwEwYHKoZI\nzj0CAQYIKoZIzj0DAQcDQgAE4ErISW/k5iZv0n7n1qpbOZcRMNmn8VqAOX4UIELm\nQ51neULt9T3pxdGEsq7B5O1ncB/RdZwf+3dihBHjngXerKNFMEMwDgYDVR0PAQH/\nBAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFP2/1CHK9OdPjs/9\np1mh3t+pyujsMAoGCCqGSM49BAMCA0gAMEUCIQDETOC8hB9EaEvdc2sdEtcNeyXu\nYryyf6I5tJC13E2hOQIgef+ymHy6eXf0jNkY6DXz041THa/67dSrXaZGgaTh4LI=\n-----END CERTIFICATE-----\n"
+                "pem": "-----BEGIN CERTIFICATE-----\nMIICCjCCAbGgAwIBAgIURV0KgZTOagIAIU7wRcSg/mKl5RUwCgYIKoZIzj0EAwIw\nYjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcg\nWW9yazEUMBIGA1UEChMLZXhhbXBsZS5jb20xFzAVBgNVBAMTDmNhLmV4YW1wbGUu\nY29tMB4XDTIyMDcwNTA5NDQwMFoXDTM3MDcwMTA5NDQwMFowYjELMAkGA1UEBhMC\nVVMxETAPBgNVBAgTCE5ldyBZb3JrMREwDwYDVQQHEwhOZXcgWW9yazEUMBIGA1UE\nChMLZXhhbXBsZS5jb20xFzAVBgNVBAMTDmNhLmV4YW1wbGUuY29tMFkwEwYHKoZI\nzj0CAQYIKoZIzj0DAQcDQgAEWrOugtJgVLAKZRw9jaC15RUbVuTm0ZmsqNyiQrKQ\nYawLE6fs+QIU7WQ25fxlYtmGB2S8nofGCDuwaoTevW0GoaNFMEMwDgYDVR0PAQH/\nBAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQEwHQYDVR0OBBYEFLKBzGXaQg2Irr57\npjoFYZ9F1NoNMAoGCCqGSM49BAMCA0cAMEQCIB1YdgOEsATw2GeaFmq6nqWg0JDT\np456JB/reFmnPWdJAiBPo5H9sMh+MpP4R5ue7nuwYK7SEJ1DOJqWMlPuNhVgtA==\n-----END CERTIFICATE-----\n"
             },
             "grpcOptions": {
                 "ssl-target-name-override": "orderer0.example.com",
diff --git a/src/dlt/src/main/kotlin/Main.kt b/src/dlt/src/main/kotlin/Main.kt
index d6298cc28..68a820ee9 100644
--- a/src/dlt/src/main/kotlin/Main.kt
+++ b/src/dlt/src/main/kotlin/Main.kt
@@ -125,8 +125,7 @@ suspend fun main(args: Array<String>) {
     }
 
     try {
-        val newRecord = Config.DltRecord.newBuilder().setId(id).setOperation(Config.DltRecordOperation.DISABLE)
-            .setType(Config.DltRecordType.SLICE).setJson("{}").build()
+        val newRecord = Config.DltRecord.newBuilder().setId(id).setOperation(Config.DltRecordOperation.DISABLE).build()
         val result = client.post<ByteArray>("http://localhost:8080/dlt/record") {
             body = newRecord.toByteArray()
         }
diff --git a/src/dlt/src/main/kotlin/fabric/FabricConnector.kt b/src/dlt/src/main/kotlin/fabric/FabricConnector.kt
index 0918f59e1..d7c163954 100644
--- a/src/dlt/src/main/kotlin/fabric/FabricConnector.kt
+++ b/src/dlt/src/main/kotlin/fabric/FabricConnector.kt
@@ -38,6 +38,7 @@
 package fabric
 
 import org.hyperledger.fabric.gateway.Contract
+import org.hyperledger.fabric.gateway.ContractEvent
 import org.hyperledger.fabric.gateway.Wallet
 import org.hyperledger.fabric.gateway.Wallets
 import org.hyperledger.fabric.sdk.security.CryptoSuiteFactory
@@ -45,6 +46,7 @@ import org.hyperledger.fabric_ca.sdk.HFCAClient
 import proto.Config
 import java.nio.file.Paths
 import java.util.*
+import java.util.function.Consumer
 
 class FabricConnector(val config: Config.DltConfig) {
     private val caClient: HFCAClient
@@ -63,6 +65,7 @@ class FabricConnector(val config: Config.DltConfig) {
         // Create a wallet for managing identities
         wallet = Wallets.newFileSystemWallet(Paths.get(config.wallet))
         contract = connect()
+        subscribeForEvents()
     }
 
     fun connect(): Contract {
@@ -102,4 +105,13 @@ class FabricConnector(val config: Config.DltConfig) {
     fun deleteData(uuid: String): String {
         return String(contract.submitTransaction("DeactivateRecord", uuid))
     }
+
+    private fun subscribeForEvents() {
+        val consumer = Consumer {
+            event: ContractEvent? -> run {
+                println(event?.payload?.get()?.let { String(it) })
+            }
+        }
+        contract.addContractListener(consumer)
+    }
 }
\ No newline at end of file
-- 
GitLab


From ea50d792ecb362b3e397417a2aa2fa29b0e0d6af Mon Sep 17 00:00:00 2001
From: Lluis Gifre <lluis.gifre@cttc.es>
Date: Wed, 6 Jul 2022 16:13:55 +0200
Subject: [PATCH 56/60] DLT component:

- restructured component and separated it into "connector" and "gateway" subcomponents.
- arranged name typos in DLT proto file
- prepared component folders for dlt-connector component
---
 proto/dlt.proto                               |   13 +-
 src/dlt/__init__.py                           |   14 +
 src/dlt/connector/__init__.py                 |   14 +
 src/dlt/connector/client/__init__.py          |   14 +
 src/dlt/connector/genproto.sh                 |   49 +
 src/dlt/connector/proto/__init__.py           |   14 +
 src/dlt/connector/proto/context_pb2.py        | 3071 +++++++++++++++++
 src/dlt/connector/proto/dlt_pb2.py            |  638 ++++
 src/dlt/connector/proto/dlt_pb2_grpc.py       |  199 ++
 .../connector/proto/kpi_sample_types_pb2.py   |   78 +
 src/dlt/connector/service/__init__.py         |   14 +
 src/dlt/connector/tests/__init__.py           |   14 +
 src/dlt/{ => gateway}/.gitignore              |    0
 src/dlt/{ => gateway}/README.md               |    0
 src/dlt/{ => gateway}/build.gradle.kts        |    0
 .../config/ca.org1.example.com-cert.pem       |    0
 .../{ => gateway}/config/connection-org1.json |    0
 src/dlt/{ => gateway}/gradle.properties       |    0
 .../gradle/wrapper/gradle-wrapper.jar         |  Bin
 .../gradle/wrapper/gradle-wrapper.properties  |    0
 src/dlt/{ => gateway}/gradlew                 |    0
 src/dlt/{ => gateway}/gradlew.bat             |    0
 src/dlt/{ => gateway}/settings.gradle.kts     |    0
 src/dlt/{ => gateway}/src/main/kotlin/Main.kt |    0
 .../src/main/kotlin/fabric/ConnectGateway.kt  |    0
 .../src/main/kotlin/fabric/EnrollAdmin.kt     |    0
 .../src/main/kotlin/fabric/FabricConnector.kt |    0
 .../src/main/kotlin/fabric/RegisterUser.kt    |    0
 .../src/main/kotlin/http/Server.kt            |    0
 .../src/main/kotlin/proto/Config.proto        |    0
 30 files changed, 4126 insertions(+), 6 deletions(-)
 create mode 100644 src/dlt/__init__.py
 create mode 100644 src/dlt/connector/__init__.py
 create mode 100644 src/dlt/connector/client/__init__.py
 create mode 100755 src/dlt/connector/genproto.sh
 create mode 100644 src/dlt/connector/proto/__init__.py
 create mode 100644 src/dlt/connector/proto/context_pb2.py
 create mode 100644 src/dlt/connector/proto/dlt_pb2.py
 create mode 100644 src/dlt/connector/proto/dlt_pb2_grpc.py
 create mode 100644 src/dlt/connector/proto/kpi_sample_types_pb2.py
 create mode 100644 src/dlt/connector/service/__init__.py
 create mode 100644 src/dlt/connector/tests/__init__.py
 rename src/dlt/{ => gateway}/.gitignore (100%)
 rename src/dlt/{ => gateway}/README.md (100%)
 rename src/dlt/{ => gateway}/build.gradle.kts (100%)
 rename src/dlt/{ => gateway}/config/ca.org1.example.com-cert.pem (100%)
 rename src/dlt/{ => gateway}/config/connection-org1.json (100%)
 rename src/dlt/{ => gateway}/gradle.properties (100%)
 rename src/dlt/{ => gateway}/gradle/wrapper/gradle-wrapper.jar (100%)
 rename src/dlt/{ => gateway}/gradle/wrapper/gradle-wrapper.properties (100%)
 rename src/dlt/{ => gateway}/gradlew (100%)
 rename src/dlt/{ => gateway}/gradlew.bat (100%)
 rename src/dlt/{ => gateway}/settings.gradle.kts (100%)
 rename src/dlt/{ => gateway}/src/main/kotlin/Main.kt (100%)
 rename src/dlt/{ => gateway}/src/main/kotlin/fabric/ConnectGateway.kt (100%)
 rename src/dlt/{ => gateway}/src/main/kotlin/fabric/EnrollAdmin.kt (100%)
 rename src/dlt/{ => gateway}/src/main/kotlin/fabric/FabricConnector.kt (100%)
 rename src/dlt/{ => gateway}/src/main/kotlin/fabric/RegisterUser.kt (100%)
 rename src/dlt/{ => gateway}/src/main/kotlin/http/Server.kt (100%)
 rename src/dlt/{ => gateway}/src/main/kotlin/proto/Config.proto (100%)

diff --git a/proto/dlt.proto b/proto/dlt.proto
index 0d5d4fe27..44fb9478f 100644
--- a/proto/dlt.proto
+++ b/proto/dlt.proto
@@ -63,16 +63,17 @@ message DltRecordId {
 }
 
 message DltRecord {
-  DltRecordId        record_id = 1;           // record identifier
-  DltRecordOperation operation = 2;           // operation to be performed over the record
-  string             data_json = 3;           // record content: JSON-encoded record content
+  DltRecordId            record_id = 1;       // record identifier
+  DltRecordOperationEnum operation = 2;       // operation to be performed over the record
+  string                 data_json = 3;       // record content: JSON-encoded record content
 }
 
 message DltRecordSubscription {
-  // retrieved events should match both conditions
+  // retrieved events have to match ALL conditions.
+  //   i.e., type in types requested, AND operation in operations requested
   // TODO: consider adding a more sophisticated filtering
-  repeated DltRecordType      type      = 1;  // only receive subscriptions of the selected types, empty=all
-  repeated DltRecordOperation operation = 2;  // only receive subscriptions of the selected operations, empty=all
+  repeated DltRecordTypeEnum      type      = 1;  // selected event types, empty=all
+  repeated DltRecordOperationEnum operation = 2;  // selected event operations, empty=all
 }
 
 message DltRecordEvent {
diff --git a/src/dlt/__init__.py b/src/dlt/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/dlt/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/dlt/connector/__init__.py b/src/dlt/connector/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/dlt/connector/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/dlt/connector/client/__init__.py b/src/dlt/connector/client/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/dlt/connector/client/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/dlt/connector/genproto.sh b/src/dlt/connector/genproto.sh
new file mode 100755
index 000000000..d06be3d7e
--- /dev/null
+++ b/src/dlt/connector/genproto.sh
@@ -0,0 +1,49 @@
+#!/bin/bash -eu
+#
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Make folder containing the script the root folder for its execution
+cd $(dirname $0)
+
+rm -rf proto/*.py
+rm -rf proto/__pycache__
+tee proto/__init__.py << EOF > /dev/null
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+EOF
+
+python -m grpc_tools.protoc -I../../../proto --python_out=proto --grpc_python_out=proto context.proto
+python -m grpc_tools.protoc -I../../../proto --python_out=proto --grpc_python_out=proto kpi_sample_types.proto
+python -m grpc_tools.protoc -I../../../proto --python_out=proto --grpc_python_out=proto dlt.proto
+
+rm proto/context_pb2_grpc.py
+rm proto/kpi_sample_types_pb2_grpc.py
+
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/context_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/dlt_pb2.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/dlt_pb2_grpc.py
+sed -i -E 's/(import\ .*)_pb2/from . \1_pb2/g' proto/kpi_sample_types_pb2.py
diff --git a/src/dlt/connector/proto/__init__.py b/src/dlt/connector/proto/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/dlt/connector/proto/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/dlt/connector/proto/context_pb2.py b/src/dlt/connector/proto/context_pb2.py
new file mode 100644
index 000000000..50d501d3a
--- /dev/null
+++ b/src/dlt/connector/proto/context_pb2.py
@@ -0,0 +1,3071 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: context.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import kpi_sample_types_pb2 as kpi__sample__types__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='context.proto',
+  package='context',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\rcontext.proto\x12\x07\x63ontext\x1a\x16kpi_sample_types.proto\"\x07\n\x05\x45mpty\"\x14\n\x04Uuid\x12\x0c\n\x04uuid\x18\x01 \x01(\t\"F\n\x05\x45vent\x12\x11\n\ttimestamp\x18\x01 \x01(\x01\x12*\n\nevent_type\x18\x02 \x01(\x0e\x32\x16.context.EventTypeEnum\"0\n\tContextId\x12#\n\x0c\x63ontext_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xb6\x01\n\x07\x43ontext\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12)\n\x0ctopology_ids\x18\x02 \x03(\x0b\x32\x13.context.TopologyId\x12\'\n\x0bservice_ids\x18\x03 \x03(\x0b\x32\x12.context.ServiceId\x12/\n\ncontroller\x18\x04 \x01(\x0b\x32\x1b.context.TeraFlowController\"8\n\rContextIdList\x12\'\n\x0b\x63ontext_ids\x18\x01 \x03(\x0b\x32\x12.context.ContextId\"1\n\x0b\x43ontextList\x12\"\n\x08\x63ontexts\x18\x01 \x03(\x0b\x32\x10.context.Context\"U\n\x0c\x43ontextEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\ncontext_id\x18\x02 \x01(\x0b\x32\x12.context.ContextId\"Z\n\nTopologyId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12$\n\rtopology_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"~\n\x08Topology\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12%\n\ndevice_ids\x18\x02 \x03(\x0b\x32\x11.context.DeviceId\x12!\n\x08link_ids\x18\x03 \x03(\x0b\x32\x0f.context.LinkId\";\n\x0eTopologyIdList\x12)\n\x0ctopology_ids\x18\x01 \x03(\x0b\x32\x13.context.TopologyId\"5\n\x0cTopologyList\x12%\n\ntopologies\x18\x01 \x03(\x0b\x32\x11.context.Topology\"X\n\rTopologyEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12(\n\x0btopology_id\x18\x02 \x01(\x0b\x32\x13.context.TopologyId\".\n\x08\x44\x65viceId\x12\"\n\x0b\x64\x65vice_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\x9a\x02\n\x06\x44\x65vice\x12$\n\tdevice_id\x18\x01 \x01(\x0b\x32\x11.context.DeviceId\x12\x13\n\x0b\x64\x65vice_type\x18\x02 \x01(\t\x12,\n\rdevice_config\x18\x03 \x01(\x0b\x32\x15.context.DeviceConfig\x12G\n\x19\x64\x65vice_operational_status\x18\x04 \x01(\x0e\x32$.context.DeviceOperationalStatusEnum\x12\x31\n\x0e\x64\x65vice_drivers\x18\x05 \x03(\x0e\x32\x19.context.DeviceDriverEnum\x12+\n\x10\x64\x65vice_endpoints\x18\x06 \x03(\x0b\x32\x11.context.EndPoint\"9\n\x0c\x44\x65viceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"5\n\x0c\x44\x65viceIdList\x12%\n\ndevice_ids\x18\x01 \x03(\x0b\x32\x11.context.DeviceId\".\n\nDeviceList\x12 \n\x07\x64\x65vices\x18\x01 \x03(\x0b\x32\x0f.context.Device\"R\n\x0b\x44\x65viceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\"*\n\x06LinkId\x12 \n\tlink_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"X\n\x04Link\x12 \n\x07link_id\x18\x01 \x01(\x0b\x32\x0f.context.LinkId\x12.\n\x11link_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\"/\n\nLinkIdList\x12!\n\x08link_ids\x18\x01 \x03(\x0b\x32\x0f.context.LinkId\"(\n\x08LinkList\x12\x1c\n\x05links\x18\x01 \x03(\x0b\x32\r.context.Link\"L\n\tLinkEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12 \n\x07link_id\x18\x02 \x01(\x0b\x32\x0f.context.LinkId\"X\n\tServiceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12#\n\x0cservice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\xa6\x02\n\x07Service\x12&\n\nservice_id\x18\x01 \x01(\x0b\x32\x12.context.ServiceId\x12.\n\x0cservice_type\x18\x02 \x01(\x0e\x32\x18.context.ServiceTypeEnum\x12\x31\n\x14service_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12\x30\n\x13service_constraints\x18\x04 \x03(\x0b\x32\x13.context.Constraint\x12.\n\x0eservice_status\x18\x05 \x01(\x0b\x32\x16.context.ServiceStatus\x12.\n\x0eservice_config\x18\x06 \x01(\x0b\x32\x16.context.ServiceConfig\"C\n\rServiceStatus\x12\x32\n\x0eservice_status\x18\x01 \x01(\x0e\x32\x1a.context.ServiceStatusEnum\":\n\rServiceConfig\x12)\n\x0c\x63onfig_rules\x18\x01 \x03(\x0b\x32\x13.context.ConfigRule\"8\n\rServiceIdList\x12\'\n\x0bservice_ids\x18\x01 \x03(\x0b\x32\x12.context.ServiceId\"1\n\x0bServiceList\x12\"\n\x08services\x18\x01 \x03(\x0b\x32\x10.context.Service\"U\n\x0cServiceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\"T\n\x07SliceId\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12!\n\nslice_uuid\x18\x02 \x01(\x0b\x32\r.context.Uuid\"\x95\x02\n\x05Slice\x12\"\n\x08slice_id\x18\x01 \x01(\x0b\x32\x10.context.SliceId\x12/\n\x12slice_endpoint_ids\x18\x02 \x03(\x0b\x32\x13.context.EndPointId\x12.\n\x11slice_constraints\x18\x03 \x03(\x0b\x32\x13.context.Constraint\x12-\n\x11slice_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\x12,\n\x12slice_subslice_ids\x18\x05 \x03(\x0b\x32\x10.context.SliceId\x12*\n\x0cslice_status\x18\x06 \x01(\x0b\x32\x14.context.SliceStatus\"=\n\x0bSliceStatus\x12.\n\x0cslice_status\x18\x01 \x01(\x0e\x32\x18.context.SliceStatusEnum\"2\n\x0bSliceIdList\x12#\n\tslice_ids\x18\x01 \x03(\x0b\x32\x10.context.SliceId\"+\n\tSliceList\x12\x1e\n\x06slices\x18\x01 \x03(\x0b\x32\x0e.context.Slice\"O\n\nSliceEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12\"\n\x08slice_id\x18\x02 \x01(\x0b\x32\x10.context.SliceId\"6\n\x0c\x43onnectionId\x12&\n\x0f\x63onnection_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\"\xc4\x01\n\nConnection\x12,\n\rconnection_id\x18\x01 \x01(\x0b\x32\x15.context.ConnectionId\x12&\n\nservice_id\x18\x02 \x01(\x0b\x32\x12.context.ServiceId\x12\x33\n\x16path_hops_endpoint_ids\x18\x03 \x03(\x0b\x32\x13.context.EndPointId\x12+\n\x0fsub_service_ids\x18\x04 \x03(\x0b\x32\x12.context.ServiceId\"A\n\x10\x43onnectionIdList\x12-\n\x0e\x63onnection_ids\x18\x01 \x03(\x0b\x32\x15.context.ConnectionId\":\n\x0e\x43onnectionList\x12(\n\x0b\x63onnections\x18\x01 \x03(\x0b\x32\x13.context.Connection\"^\n\x0f\x43onnectionEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12,\n\rconnection_id\x18\x02 \x01(\x0b\x32\x15.context.ConnectionId\"\x82\x01\n\nEndPointId\x12(\n\x0btopology_id\x18\x01 \x01(\x0b\x32\x13.context.TopologyId\x12$\n\tdevice_id\x18\x02 \x01(\x0b\x32\x11.context.DeviceId\x12$\n\rendpoint_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"\x86\x01\n\x08\x45ndPoint\x12(\n\x0b\x65ndpoint_id\x18\x01 \x01(\x0b\x32\x13.context.EndPointId\x12\x15\n\rendpoint_type\x18\x02 \x01(\t\x12\x39\n\x10kpi_sample_types\x18\x03 \x03(\x0e\x32\x1f.kpi_sample_types.KpiSampleType\"e\n\nConfigRule\x12)\n\x06\x61\x63tion\x18\x01 \x01(\x0e\x32\x19.context.ConfigActionEnum\x12\x14\n\x0cresource_key\x18\x02 \x01(\t\x12\x16\n\x0eresource_value\x18\x03 \x01(\t\"?\n\nConstraint\x12\x17\n\x0f\x63onstraint_type\x18\x01 \x01(\t\x12\x18\n\x10\x63onstraint_value\x18\x02 \x01(\t\"^\n\x12TeraFlowController\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x12\n\nip_address\x18\x02 \x01(\t\x12\x0c\n\x04port\x18\x03 \x01(\r\"U\n\x14\x41uthenticationResult\x12&\n\ncontext_id\x18\x01 \x01(\x0b\x32\x12.context.ContextId\x12\x15\n\rauthenticated\x18\x02 \x01(\x08*j\n\rEventTypeEnum\x12\x17\n\x13\x45VENTTYPE_UNDEFINED\x10\x00\x12\x14\n\x10\x45VENTTYPE_CREATE\x10\x01\x12\x14\n\x10\x45VENTTYPE_UPDATE\x10\x02\x12\x14\n\x10\x45VENTTYPE_REMOVE\x10\x03*\xc5\x01\n\x10\x44\x65viceDriverEnum\x12\x1a\n\x16\x44\x45VICEDRIVER_UNDEFINED\x10\x00\x12\x1b\n\x17\x44\x45VICEDRIVER_OPENCONFIG\x10\x01\x12\x1e\n\x1a\x44\x45VICEDRIVER_TRANSPORT_API\x10\x02\x12\x13\n\x0f\x44\x45VICEDRIVER_P4\x10\x03\x12&\n\"DEVICEDRIVER_IETF_NETWORK_TOPOLOGY\x10\x04\x12\x1b\n\x17\x44\x45VICEDRIVER_ONF_TR_352\x10\x05*\x8f\x01\n\x1b\x44\x65viceOperationalStatusEnum\x12%\n!DEVICEOPERATIONALSTATUS_UNDEFINED\x10\x00\x12$\n DEVICEOPERATIONALSTATUS_DISABLED\x10\x01\x12#\n\x1f\x44\x45VICEOPERATIONALSTATUS_ENABLED\x10\x02*\x81\x01\n\x0fServiceTypeEnum\x12\x17\n\x13SERVICETYPE_UNKNOWN\x10\x00\x12\x14\n\x10SERVICETYPE_L3NM\x10\x01\x12\x14\n\x10SERVICETYPE_L2NM\x10\x02\x12)\n%SERVICETYPE_TAPI_CONNECTIVITY_SERVICE\x10\x03*\x88\x01\n\x11ServiceStatusEnum\x12\x1b\n\x17SERVICESTATUS_UNDEFINED\x10\x00\x12\x19\n\x15SERVICESTATUS_PLANNED\x10\x01\x12\x18\n\x14SERVICESTATUS_ACTIVE\x10\x02\x12!\n\x1dSERVICESTATUS_PENDING_REMOVAL\x10\x03*\x8b\x01\n\x0fSliceStatusEnum\x12\x19\n\x15SLICESTATUS_UNDEFINED\x10\x00\x12\x17\n\x13SLICESTATUS_PLANNED\x10\x01\x12\x14\n\x10SLICESTATUS_INIT\x10\x02\x12\x16\n\x12SLICESTATUS_ACTIVE\x10\x03\x12\x16\n\x12SLICESTATUS_DEINIT\x10\x04*]\n\x10\x43onfigActionEnum\x12\x1a\n\x16\x43ONFIGACTION_UNDEFINED\x10\x00\x12\x14\n\x10\x43ONFIGACTION_SET\x10\x01\x12\x17\n\x13\x43ONFIGACTION_DELETE\x10\x02\x32\xef\x12\n\x0e\x43ontextService\x12:\n\x0eListContextIds\x12\x0e.context.Empty\x1a\x16.context.ContextIdList\"\x00\x12\x36\n\x0cListContexts\x12\x0e.context.Empty\x1a\x14.context.ContextList\"\x00\x12\x34\n\nGetContext\x12\x12.context.ContextId\x1a\x10.context.Context\"\x00\x12\x34\n\nSetContext\x12\x10.context.Context\x1a\x12.context.ContextId\"\x00\x12\x35\n\rRemoveContext\x12\x12.context.ContextId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetContextEvents\x12\x0e.context.Empty\x1a\x15.context.ContextEvent\"\x00\x30\x01\x12@\n\x0fListTopologyIds\x12\x12.context.ContextId\x1a\x17.context.TopologyIdList\"\x00\x12=\n\x0eListTopologies\x12\x12.context.ContextId\x1a\x15.context.TopologyList\"\x00\x12\x37\n\x0bGetTopology\x12\x13.context.TopologyId\x1a\x11.context.Topology\"\x00\x12\x37\n\x0bSetTopology\x12\x11.context.Topology\x1a\x13.context.TopologyId\"\x00\x12\x37\n\x0eRemoveTopology\x12\x13.context.TopologyId\x1a\x0e.context.Empty\"\x00\x12?\n\x11GetTopologyEvents\x12\x0e.context.Empty\x1a\x16.context.TopologyEvent\"\x00\x30\x01\x12\x38\n\rListDeviceIds\x12\x0e.context.Empty\x1a\x15.context.DeviceIdList\"\x00\x12\x34\n\x0bListDevices\x12\x0e.context.Empty\x1a\x13.context.DeviceList\"\x00\x12\x31\n\tGetDevice\x12\x11.context.DeviceId\x1a\x0f.context.Device\"\x00\x12\x31\n\tSetDevice\x12\x0f.context.Device\x1a\x11.context.DeviceId\"\x00\x12\x33\n\x0cRemoveDevice\x12\x11.context.DeviceId\x1a\x0e.context.Empty\"\x00\x12;\n\x0fGetDeviceEvents\x12\x0e.context.Empty\x1a\x14.context.DeviceEvent\"\x00\x30\x01\x12\x34\n\x0bListLinkIds\x12\x0e.context.Empty\x1a\x13.context.LinkIdList\"\x00\x12\x30\n\tListLinks\x12\x0e.context.Empty\x1a\x11.context.LinkList\"\x00\x12+\n\x07GetLink\x12\x0f.context.LinkId\x1a\r.context.Link\"\x00\x12+\n\x07SetLink\x12\r.context.Link\x1a\x0f.context.LinkId\"\x00\x12/\n\nRemoveLink\x12\x0f.context.LinkId\x1a\x0e.context.Empty\"\x00\x12\x37\n\rGetLinkEvents\x12\x0e.context.Empty\x1a\x12.context.LinkEvent\"\x00\x30\x01\x12>\n\x0eListServiceIds\x12\x12.context.ContextId\x1a\x16.context.ServiceIdList\"\x00\x12:\n\x0cListServices\x12\x12.context.ContextId\x1a\x14.context.ServiceList\"\x00\x12\x34\n\nGetService\x12\x12.context.ServiceId\x1a\x10.context.Service\"\x00\x12\x34\n\nSetService\x12\x10.context.Service\x1a\x12.context.ServiceId\"\x00\x12\x35\n\rRemoveService\x12\x12.context.ServiceId\x1a\x0e.context.Empty\"\x00\x12=\n\x10GetServiceEvents\x12\x0e.context.Empty\x1a\x15.context.ServiceEvent\"\x00\x30\x01\x12:\n\x0cListSliceIds\x12\x12.context.ContextId\x1a\x14.context.SliceIdList\"\x00\x12\x36\n\nListSlices\x12\x12.context.ContextId\x1a\x12.context.SliceList\"\x00\x12.\n\x08GetSlice\x12\x10.context.SliceId\x1a\x0e.context.Slice\"\x00\x12.\n\x08SetSlice\x12\x0e.context.Slice\x1a\x10.context.SliceId\"\x00\x12\x31\n\x0bRemoveSlice\x12\x10.context.SliceId\x1a\x0e.context.Empty\"\x00\x12\x39\n\x0eGetSliceEvents\x12\x0e.context.Empty\x1a\x13.context.SliceEvent\"\x00\x30\x01\x12\x44\n\x11ListConnectionIds\x12\x12.context.ServiceId\x1a\x19.context.ConnectionIdList\"\x00\x12@\n\x0fListConnections\x12\x12.context.ServiceId\x1a\x17.context.ConnectionList\"\x00\x12=\n\rGetConnection\x12\x15.context.ConnectionId\x1a\x13.context.Connection\"\x00\x12=\n\rSetConnection\x12\x13.context.Connection\x1a\x15.context.ConnectionId\"\x00\x12;\n\x10RemoveConnection\x12\x15.context.ConnectionId\x1a\x0e.context.Empty\"\x00\x12\x43\n\x13GetConnectionEvents\x12\x0e.context.Empty\x1a\x18.context.ConnectionEvent\"\x00\x30\x01\x62\x06proto3'
+  ,
+  dependencies=[kpi__sample__types__pb2.DESCRIPTOR,])
+
+_EVENTTYPEENUM = _descriptor.EnumDescriptor(
+  name='EventTypeEnum',
+  full_name='context.EventTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_CREATE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_UPDATE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='EVENTTYPE_REMOVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4310,
+  serialized_end=4416,
+)
+_sym_db.RegisterEnumDescriptor(_EVENTTYPEENUM)
+
+EventTypeEnum = enum_type_wrapper.EnumTypeWrapper(_EVENTTYPEENUM)
+_DEVICEDRIVERENUM = _descriptor.EnumDescriptor(
+  name='DeviceDriverEnum',
+  full_name='context.DeviceDriverEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_OPENCONFIG', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_TRANSPORT_API', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_P4', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_IETF_NETWORK_TOPOLOGY', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEDRIVER_ONF_TR_352', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4419,
+  serialized_end=4616,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEDRIVERENUM)
+
+DeviceDriverEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEDRIVERENUM)
+_DEVICEOPERATIONALSTATUSENUM = _descriptor.EnumDescriptor(
+  name='DeviceOperationalStatusEnum',
+  full_name='context.DeviceOperationalStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_DISABLED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DEVICEOPERATIONALSTATUS_ENABLED', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4619,
+  serialized_end=4762,
+)
+_sym_db.RegisterEnumDescriptor(_DEVICEOPERATIONALSTATUSENUM)
+
+DeviceOperationalStatusEnum = enum_type_wrapper.EnumTypeWrapper(_DEVICEOPERATIONALSTATUSENUM)
+_SERVICETYPEENUM = _descriptor.EnumDescriptor(
+  name='ServiceTypeEnum',
+  full_name='context.ServiceTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L3NM', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_L2NM', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICETYPE_TAPI_CONNECTIVITY_SERVICE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4765,
+  serialized_end=4894,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICETYPEENUM)
+
+ServiceTypeEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICETYPEENUM)
+_SERVICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='ServiceStatusEnum',
+  full_name='context.ServiceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_ACTIVE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SERVICESTATUS_PENDING_REMOVAL', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=4897,
+  serialized_end=5033,
+)
+_sym_db.RegisterEnumDescriptor(_SERVICESTATUSENUM)
+
+ServiceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SERVICESTATUSENUM)
+_SLICESTATUSENUM = _descriptor.EnumDescriptor(
+  name='SliceStatusEnum',
+  full_name='context.SliceStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_PLANNED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_INIT', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_ACTIVE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='SLICESTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5036,
+  serialized_end=5175,
+)
+_sym_db.RegisterEnumDescriptor(_SLICESTATUSENUM)
+
+SliceStatusEnum = enum_type_wrapper.EnumTypeWrapper(_SLICESTATUSENUM)
+_CONFIGACTIONENUM = _descriptor.EnumDescriptor(
+  name='ConfigActionEnum',
+  full_name='context.ConfigActionEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_SET', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='CONFIGACTION_DELETE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=5177,
+  serialized_end=5270,
+)
+_sym_db.RegisterEnumDescriptor(_CONFIGACTIONENUM)
+
+ConfigActionEnum = enum_type_wrapper.EnumTypeWrapper(_CONFIGACTIONENUM)
+EVENTTYPE_UNDEFINED = 0
+EVENTTYPE_CREATE = 1
+EVENTTYPE_UPDATE = 2
+EVENTTYPE_REMOVE = 3
+DEVICEDRIVER_UNDEFINED = 0
+DEVICEDRIVER_OPENCONFIG = 1
+DEVICEDRIVER_TRANSPORT_API = 2
+DEVICEDRIVER_P4 = 3
+DEVICEDRIVER_IETF_NETWORK_TOPOLOGY = 4
+DEVICEDRIVER_ONF_TR_352 = 5
+DEVICEOPERATIONALSTATUS_UNDEFINED = 0
+DEVICEOPERATIONALSTATUS_DISABLED = 1
+DEVICEOPERATIONALSTATUS_ENABLED = 2
+SERVICETYPE_UNKNOWN = 0
+SERVICETYPE_L3NM = 1
+SERVICETYPE_L2NM = 2
+SERVICETYPE_TAPI_CONNECTIVITY_SERVICE = 3
+SERVICESTATUS_UNDEFINED = 0
+SERVICESTATUS_PLANNED = 1
+SERVICESTATUS_ACTIVE = 2
+SERVICESTATUS_PENDING_REMOVAL = 3
+SLICESTATUS_UNDEFINED = 0
+SLICESTATUS_PLANNED = 1
+SLICESTATUS_INIT = 2
+SLICESTATUS_ACTIVE = 3
+SLICESTATUS_DEINIT = 4
+CONFIGACTION_UNDEFINED = 0
+CONFIGACTION_SET = 1
+CONFIGACTION_DELETE = 2
+
+
+
+_EMPTY = _descriptor.Descriptor(
+  name='Empty',
+  full_name='context.Empty',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=50,
+  serialized_end=57,
+)
+
+
+_UUID = _descriptor.Descriptor(
+  name='Uuid',
+  full_name='context.Uuid',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='uuid', full_name='context.Uuid.uuid', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=59,
+  serialized_end=79,
+)
+
+
+_EVENT = _descriptor.Descriptor(
+  name='Event',
+  full_name='context.Event',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='timestamp', full_name='context.Event.timestamp', index=0,
+      number=1, type=1, cpp_type=5, label=1,
+      has_default_value=False, default_value=float(0),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='event_type', full_name='context.Event.event_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=81,
+  serialized_end=151,
+)
+
+
+_CONTEXTID = _descriptor.Descriptor(
+  name='ContextId',
+  full_name='context.ContextId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_uuid', full_name='context.ContextId.context_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=153,
+  serialized_end=201,
+)
+
+
+_CONTEXT = _descriptor.Descriptor(
+  name='Context',
+  full_name='context.Context',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.Context.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.Context.topology_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.Context.service_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='controller', full_name='context.Context.controller', index=3,
+      number=4, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=204,
+  serialized_end=386,
+)
+
+
+_CONTEXTIDLIST = _descriptor.Descriptor(
+  name='ContextIdList',
+  full_name='context.ContextIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_ids', full_name='context.ContextIdList.context_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=388,
+  serialized_end=444,
+)
+
+
+_CONTEXTLIST = _descriptor.Descriptor(
+  name='ContextList',
+  full_name='context.ContextList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='contexts', full_name='context.ContextList.contexts', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=446,
+  serialized_end=495,
+)
+
+
+_CONTEXTEVENT = _descriptor.Descriptor(
+  name='ContextEvent',
+  full_name='context.ContextEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ContextEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ContextEvent.context_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=497,
+  serialized_end=582,
+)
+
+
+_TOPOLOGYID = _descriptor.Descriptor(
+  name='TopologyId',
+  full_name='context.TopologyId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TopologyId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_uuid', full_name='context.TopologyId.topology_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=584,
+  serialized_end=674,
+)
+
+
+_TOPOLOGY = _descriptor.Descriptor(
+  name='Topology',
+  full_name='context.Topology',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.Topology.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.Topology.device_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.Topology.link_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=676,
+  serialized_end=802,
+)
+
+
+_TOPOLOGYIDLIST = _descriptor.Descriptor(
+  name='TopologyIdList',
+  full_name='context.TopologyIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_ids', full_name='context.TopologyIdList.topology_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=804,
+  serialized_end=863,
+)
+
+
+_TOPOLOGYLIST = _descriptor.Descriptor(
+  name='TopologyList',
+  full_name='context.TopologyList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topologies', full_name='context.TopologyList.topologies', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=865,
+  serialized_end=918,
+)
+
+
+_TOPOLOGYEVENT = _descriptor.Descriptor(
+  name='TopologyEvent',
+  full_name='context.TopologyEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.TopologyEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.TopologyEvent.topology_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=920,
+  serialized_end=1008,
+)
+
+
+_DEVICEID = _descriptor.Descriptor(
+  name='DeviceId',
+  full_name='context.DeviceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_uuid', full_name='context.DeviceId.device_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1010,
+  serialized_end=1056,
+)
+
+
+_DEVICE = _descriptor.Descriptor(
+  name='Device',
+  full_name='context.Device',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.Device.device_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_type', full_name='context.Device.device_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_config', full_name='context.Device.device_config', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_operational_status', full_name='context.Device.device_operational_status', index=3,
+      number=4, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_drivers', full_name='context.Device.device_drivers', index=4,
+      number=5, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_endpoints', full_name='context.Device.device_endpoints', index=5,
+      number=6, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1059,
+  serialized_end=1341,
+)
+
+
+_DEVICECONFIG = _descriptor.Descriptor(
+  name='DeviceConfig',
+  full_name='context.DeviceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.DeviceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1343,
+  serialized_end=1400,
+)
+
+
+_DEVICEIDLIST = _descriptor.Descriptor(
+  name='DeviceIdList',
+  full_name='context.DeviceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='device_ids', full_name='context.DeviceIdList.device_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1402,
+  serialized_end=1455,
+)
+
+
+_DEVICELIST = _descriptor.Descriptor(
+  name='DeviceList',
+  full_name='context.DeviceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='devices', full_name='context.DeviceList.devices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1457,
+  serialized_end=1503,
+)
+
+
+_DEVICEEVENT = _descriptor.Descriptor(
+  name='DeviceEvent',
+  full_name='context.DeviceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.DeviceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.DeviceEvent.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1505,
+  serialized_end=1587,
+)
+
+
+_LINKID = _descriptor.Descriptor(
+  name='LinkId',
+  full_name='context.LinkId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_uuid', full_name='context.LinkId.link_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1589,
+  serialized_end=1631,
+)
+
+
+_LINK = _descriptor.Descriptor(
+  name='Link',
+  full_name='context.Link',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.Link.link_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_endpoint_ids', full_name='context.Link.link_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1633,
+  serialized_end=1721,
+)
+
+
+_LINKIDLIST = _descriptor.Descriptor(
+  name='LinkIdList',
+  full_name='context.LinkIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='link_ids', full_name='context.LinkIdList.link_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1723,
+  serialized_end=1770,
+)
+
+
+_LINKLIST = _descriptor.Descriptor(
+  name='LinkList',
+  full_name='context.LinkList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='links', full_name='context.LinkList.links', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1772,
+  serialized_end=1812,
+)
+
+
+_LINKEVENT = _descriptor.Descriptor(
+  name='LinkEvent',
+  full_name='context.LinkEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.LinkEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='link_id', full_name='context.LinkEvent.link_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1814,
+  serialized_end=1890,
+)
+
+
+_SERVICEID = _descriptor.Descriptor(
+  name='ServiceId',
+  full_name='context.ServiceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.ServiceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_uuid', full_name='context.ServiceId.service_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1892,
+  serialized_end=1980,
+)
+
+
+_SERVICE = _descriptor.Descriptor(
+  name='Service',
+  full_name='context.Service',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Service.service_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_type', full_name='context.Service.service_type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_endpoint_ids', full_name='context.Service.service_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_constraints', full_name='context.Service.service_constraints', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.Service.service_status', index=4,
+      number=5, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_config', full_name='context.Service.service_config', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=1983,
+  serialized_end=2277,
+)
+
+
+_SERVICESTATUS = _descriptor.Descriptor(
+  name='ServiceStatus',
+  full_name='context.ServiceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_status', full_name='context.ServiceStatus.service_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2279,
+  serialized_end=2346,
+)
+
+
+_SERVICECONFIG = _descriptor.Descriptor(
+  name='ServiceConfig',
+  full_name='context.ServiceConfig',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='config_rules', full_name='context.ServiceConfig.config_rules', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2348,
+  serialized_end=2406,
+)
+
+
+_SERVICEIDLIST = _descriptor.Descriptor(
+  name='ServiceIdList',
+  full_name='context.ServiceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='service_ids', full_name='context.ServiceIdList.service_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2408,
+  serialized_end=2464,
+)
+
+
+_SERVICELIST = _descriptor.Descriptor(
+  name='ServiceList',
+  full_name='context.ServiceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='services', full_name='context.ServiceList.services', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2466,
+  serialized_end=2515,
+)
+
+
+_SERVICEEVENT = _descriptor.Descriptor(
+  name='ServiceEvent',
+  full_name='context.ServiceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ServiceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.ServiceEvent.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2517,
+  serialized_end=2602,
+)
+
+
+_SLICEID = _descriptor.Descriptor(
+  name='SliceId',
+  full_name='context.SliceId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.SliceId.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_uuid', full_name='context.SliceId.slice_uuid', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2604,
+  serialized_end=2688,
+)
+
+
+_SLICE = _descriptor.Descriptor(
+  name='Slice',
+  full_name='context.Slice',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.Slice.slice_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_endpoint_ids', full_name='context.Slice.slice_endpoint_ids', index=1,
+      number=2, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_constraints', full_name='context.Slice.slice_constraints', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_service_ids', full_name='context.Slice.slice_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_subslice_ids', full_name='context.Slice.slice_subslice_ids', index=4,
+      number=5, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.Slice.slice_status', index=5,
+      number=6, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2691,
+  serialized_end=2968,
+)
+
+
+_SLICESTATUS = _descriptor.Descriptor(
+  name='SliceStatus',
+  full_name='context.SliceStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_status', full_name='context.SliceStatus.slice_status', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=2970,
+  serialized_end=3031,
+)
+
+
+_SLICEIDLIST = _descriptor.Descriptor(
+  name='SliceIdList',
+  full_name='context.SliceIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slice_ids', full_name='context.SliceIdList.slice_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3033,
+  serialized_end=3083,
+)
+
+
+_SLICELIST = _descriptor.Descriptor(
+  name='SliceList',
+  full_name='context.SliceList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='slices', full_name='context.SliceList.slices', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3085,
+  serialized_end=3128,
+)
+
+
+_SLICEEVENT = _descriptor.Descriptor(
+  name='SliceEvent',
+  full_name='context.SliceEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.SliceEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='slice_id', full_name='context.SliceEvent.slice_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3130,
+  serialized_end=3209,
+)
+
+
+_CONNECTIONID = _descriptor.Descriptor(
+  name='ConnectionId',
+  full_name='context.ConnectionId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_uuid', full_name='context.ConnectionId.connection_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3211,
+  serialized_end=3265,
+)
+
+
+_CONNECTION = _descriptor.Descriptor(
+  name='Connection',
+  full_name='context.Connection',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.Connection.connection_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='service_id', full_name='context.Connection.service_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='path_hops_endpoint_ids', full_name='context.Connection.path_hops_endpoint_ids', index=2,
+      number=3, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='sub_service_ids', full_name='context.Connection.sub_service_ids', index=3,
+      number=4, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3268,
+  serialized_end=3464,
+)
+
+
+_CONNECTIONIDLIST = _descriptor.Descriptor(
+  name='ConnectionIdList',
+  full_name='context.ConnectionIdList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connection_ids', full_name='context.ConnectionIdList.connection_ids', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3466,
+  serialized_end=3531,
+)
+
+
+_CONNECTIONLIST = _descriptor.Descriptor(
+  name='ConnectionList',
+  full_name='context.ConnectionList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='connections', full_name='context.ConnectionList.connections', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3533,
+  serialized_end=3591,
+)
+
+
+_CONNECTIONEVENT = _descriptor.Descriptor(
+  name='ConnectionEvent',
+  full_name='context.ConnectionEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='context.ConnectionEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='connection_id', full_name='context.ConnectionEvent.connection_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3593,
+  serialized_end=3687,
+)
+
+
+_ENDPOINTID = _descriptor.Descriptor(
+  name='EndPointId',
+  full_name='context.EndPointId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='topology_id', full_name='context.EndPointId.topology_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='device_id', full_name='context.EndPointId.device_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_uuid', full_name='context.EndPointId.endpoint_uuid', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3690,
+  serialized_end=3820,
+)
+
+
+_ENDPOINT = _descriptor.Descriptor(
+  name='EndPoint',
+  full_name='context.EndPoint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='endpoint_id', full_name='context.EndPoint.endpoint_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='endpoint_type', full_name='context.EndPoint.endpoint_type', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='kpi_sample_types', full_name='context.EndPoint.kpi_sample_types', index=2,
+      number=3, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3823,
+  serialized_end=3957,
+)
+
+
+_CONFIGRULE = _descriptor.Descriptor(
+  name='ConfigRule',
+  full_name='context.ConfigRule',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='action', full_name='context.ConfigRule.action', index=0,
+      number=1, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_key', full_name='context.ConfigRule.resource_key', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='resource_value', full_name='context.ConfigRule.resource_value', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=3959,
+  serialized_end=4060,
+)
+
+
+_CONSTRAINT = _descriptor.Descriptor(
+  name='Constraint',
+  full_name='context.Constraint',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='constraint_type', full_name='context.Constraint.constraint_type', index=0,
+      number=1, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='constraint_value', full_name='context.Constraint.constraint_value', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4062,
+  serialized_end=4125,
+)
+
+
+_TERAFLOWCONTROLLER = _descriptor.Descriptor(
+  name='TeraFlowController',
+  full_name='context.TeraFlowController',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.TeraFlowController.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='ip_address', full_name='context.TeraFlowController.ip_address', index=1,
+      number=2, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='port', full_name='context.TeraFlowController.port', index=2,
+      number=3, type=13, cpp_type=3, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4127,
+  serialized_end=4221,
+)
+
+
+_AUTHENTICATIONRESULT = _descriptor.Descriptor(
+  name='AuthenticationResult',
+  full_name='context.AuthenticationResult',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='context_id', full_name='context.AuthenticationResult.context_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='authenticated', full_name='context.AuthenticationResult.authenticated', index=1,
+      number=2, type=8, cpp_type=7, label=1,
+      has_default_value=False, default_value=False,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=4223,
+  serialized_end=4308,
+)
+
+_EVENT.fields_by_name['event_type'].enum_type = _EVENTTYPEENUM
+_CONTEXTID.fields_by_name['context_uuid'].message_type = _UUID
+_CONTEXT.fields_by_name['context_id'].message_type = _CONTEXTID
+_CONTEXT.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_CONTEXT.fields_by_name['service_ids'].message_type = _SERVICEID
+_CONTEXT.fields_by_name['controller'].message_type = _TERAFLOWCONTROLLER
+_CONTEXTIDLIST.fields_by_name['context_ids'].message_type = _CONTEXTID
+_CONTEXTLIST.fields_by_name['contexts'].message_type = _CONTEXT
+_CONTEXTEVENT.fields_by_name['event'].message_type = _EVENT
+_CONTEXTEVENT.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['context_id'].message_type = _CONTEXTID
+_TOPOLOGYID.fields_by_name['topology_uuid'].message_type = _UUID
+_TOPOLOGY.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_TOPOLOGY.fields_by_name['device_ids'].message_type = _DEVICEID
+_TOPOLOGY.fields_by_name['link_ids'].message_type = _LINKID
+_TOPOLOGYIDLIST.fields_by_name['topology_ids'].message_type = _TOPOLOGYID
+_TOPOLOGYLIST.fields_by_name['topologies'].message_type = _TOPOLOGY
+_TOPOLOGYEVENT.fields_by_name['event'].message_type = _EVENT
+_TOPOLOGYEVENT.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_DEVICEID.fields_by_name['device_uuid'].message_type = _UUID
+_DEVICE.fields_by_name['device_id'].message_type = _DEVICEID
+_DEVICE.fields_by_name['device_config'].message_type = _DEVICECONFIG
+_DEVICE.fields_by_name['device_operational_status'].enum_type = _DEVICEOPERATIONALSTATUSENUM
+_DEVICE.fields_by_name['device_drivers'].enum_type = _DEVICEDRIVERENUM
+_DEVICE.fields_by_name['device_endpoints'].message_type = _ENDPOINT
+_DEVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_DEVICEIDLIST.fields_by_name['device_ids'].message_type = _DEVICEID
+_DEVICELIST.fields_by_name['devices'].message_type = _DEVICE
+_DEVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_DEVICEEVENT.fields_by_name['device_id'].message_type = _DEVICEID
+_LINKID.fields_by_name['link_uuid'].message_type = _UUID
+_LINK.fields_by_name['link_id'].message_type = _LINKID
+_LINK.fields_by_name['link_endpoint_ids'].message_type = _ENDPOINTID
+_LINKIDLIST.fields_by_name['link_ids'].message_type = _LINKID
+_LINKLIST.fields_by_name['links'].message_type = _LINK
+_LINKEVENT.fields_by_name['event'].message_type = _EVENT
+_LINKEVENT.fields_by_name['link_id'].message_type = _LINKID
+_SERVICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SERVICEID.fields_by_name['service_uuid'].message_type = _UUID
+_SERVICE.fields_by_name['service_id'].message_type = _SERVICEID
+_SERVICE.fields_by_name['service_type'].enum_type = _SERVICETYPEENUM
+_SERVICE.fields_by_name['service_endpoint_ids'].message_type = _ENDPOINTID
+_SERVICE.fields_by_name['service_constraints'].message_type = _CONSTRAINT
+_SERVICE.fields_by_name['service_status'].message_type = _SERVICESTATUS
+_SERVICE.fields_by_name['service_config'].message_type = _SERVICECONFIG
+_SERVICESTATUS.fields_by_name['service_status'].enum_type = _SERVICESTATUSENUM
+_SERVICECONFIG.fields_by_name['config_rules'].message_type = _CONFIGRULE
+_SERVICEIDLIST.fields_by_name['service_ids'].message_type = _SERVICEID
+_SERVICELIST.fields_by_name['services'].message_type = _SERVICE
+_SERVICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SERVICEEVENT.fields_by_name['service_id'].message_type = _SERVICEID
+_SLICEID.fields_by_name['context_id'].message_type = _CONTEXTID
+_SLICEID.fields_by_name['slice_uuid'].message_type = _UUID
+_SLICE.fields_by_name['slice_id'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_endpoint_ids'].message_type = _ENDPOINTID
+_SLICE.fields_by_name['slice_constraints'].message_type = _CONSTRAINT
+_SLICE.fields_by_name['slice_service_ids'].message_type = _SERVICEID
+_SLICE.fields_by_name['slice_subslice_ids'].message_type = _SLICEID
+_SLICE.fields_by_name['slice_status'].message_type = _SLICESTATUS
+_SLICESTATUS.fields_by_name['slice_status'].enum_type = _SLICESTATUSENUM
+_SLICEIDLIST.fields_by_name['slice_ids'].message_type = _SLICEID
+_SLICELIST.fields_by_name['slices'].message_type = _SLICE
+_SLICEEVENT.fields_by_name['event'].message_type = _EVENT
+_SLICEEVENT.fields_by_name['slice_id'].message_type = _SLICEID
+_CONNECTIONID.fields_by_name['connection_uuid'].message_type = _UUID
+_CONNECTION.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_CONNECTION.fields_by_name['service_id'].message_type = _SERVICEID
+_CONNECTION.fields_by_name['path_hops_endpoint_ids'].message_type = _ENDPOINTID
+_CONNECTION.fields_by_name['sub_service_ids'].message_type = _SERVICEID
+_CONNECTIONIDLIST.fields_by_name['connection_ids'].message_type = _CONNECTIONID
+_CONNECTIONLIST.fields_by_name['connections'].message_type = _CONNECTION
+_CONNECTIONEVENT.fields_by_name['event'].message_type = _EVENT
+_CONNECTIONEVENT.fields_by_name['connection_id'].message_type = _CONNECTIONID
+_ENDPOINTID.fields_by_name['topology_id'].message_type = _TOPOLOGYID
+_ENDPOINTID.fields_by_name['device_id'].message_type = _DEVICEID
+_ENDPOINTID.fields_by_name['endpoint_uuid'].message_type = _UUID
+_ENDPOINT.fields_by_name['endpoint_id'].message_type = _ENDPOINTID
+_ENDPOINT.fields_by_name['kpi_sample_types'].enum_type = kpi__sample__types__pb2._KPISAMPLETYPE
+_CONFIGRULE.fields_by_name['action'].enum_type = _CONFIGACTIONENUM
+_TERAFLOWCONTROLLER.fields_by_name['context_id'].message_type = _CONTEXTID
+_AUTHENTICATIONRESULT.fields_by_name['context_id'].message_type = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Empty'] = _EMPTY
+DESCRIPTOR.message_types_by_name['Uuid'] = _UUID
+DESCRIPTOR.message_types_by_name['Event'] = _EVENT
+DESCRIPTOR.message_types_by_name['ContextId'] = _CONTEXTID
+DESCRIPTOR.message_types_by_name['Context'] = _CONTEXT
+DESCRIPTOR.message_types_by_name['ContextIdList'] = _CONTEXTIDLIST
+DESCRIPTOR.message_types_by_name['ContextList'] = _CONTEXTLIST
+DESCRIPTOR.message_types_by_name['ContextEvent'] = _CONTEXTEVENT
+DESCRIPTOR.message_types_by_name['TopologyId'] = _TOPOLOGYID
+DESCRIPTOR.message_types_by_name['Topology'] = _TOPOLOGY
+DESCRIPTOR.message_types_by_name['TopologyIdList'] = _TOPOLOGYIDLIST
+DESCRIPTOR.message_types_by_name['TopologyList'] = _TOPOLOGYLIST
+DESCRIPTOR.message_types_by_name['TopologyEvent'] = _TOPOLOGYEVENT
+DESCRIPTOR.message_types_by_name['DeviceId'] = _DEVICEID
+DESCRIPTOR.message_types_by_name['Device'] = _DEVICE
+DESCRIPTOR.message_types_by_name['DeviceConfig'] = _DEVICECONFIG
+DESCRIPTOR.message_types_by_name['DeviceIdList'] = _DEVICEIDLIST
+DESCRIPTOR.message_types_by_name['DeviceList'] = _DEVICELIST
+DESCRIPTOR.message_types_by_name['DeviceEvent'] = _DEVICEEVENT
+DESCRIPTOR.message_types_by_name['LinkId'] = _LINKID
+DESCRIPTOR.message_types_by_name['Link'] = _LINK
+DESCRIPTOR.message_types_by_name['LinkIdList'] = _LINKIDLIST
+DESCRIPTOR.message_types_by_name['LinkList'] = _LINKLIST
+DESCRIPTOR.message_types_by_name['LinkEvent'] = _LINKEVENT
+DESCRIPTOR.message_types_by_name['ServiceId'] = _SERVICEID
+DESCRIPTOR.message_types_by_name['Service'] = _SERVICE
+DESCRIPTOR.message_types_by_name['ServiceStatus'] = _SERVICESTATUS
+DESCRIPTOR.message_types_by_name['ServiceConfig'] = _SERVICECONFIG
+DESCRIPTOR.message_types_by_name['ServiceIdList'] = _SERVICEIDLIST
+DESCRIPTOR.message_types_by_name['ServiceList'] = _SERVICELIST
+DESCRIPTOR.message_types_by_name['ServiceEvent'] = _SERVICEEVENT
+DESCRIPTOR.message_types_by_name['SliceId'] = _SLICEID
+DESCRIPTOR.message_types_by_name['Slice'] = _SLICE
+DESCRIPTOR.message_types_by_name['SliceStatus'] = _SLICESTATUS
+DESCRIPTOR.message_types_by_name['SliceIdList'] = _SLICEIDLIST
+DESCRIPTOR.message_types_by_name['SliceList'] = _SLICELIST
+DESCRIPTOR.message_types_by_name['SliceEvent'] = _SLICEEVENT
+DESCRIPTOR.message_types_by_name['ConnectionId'] = _CONNECTIONID
+DESCRIPTOR.message_types_by_name['Connection'] = _CONNECTION
+DESCRIPTOR.message_types_by_name['ConnectionIdList'] = _CONNECTIONIDLIST
+DESCRIPTOR.message_types_by_name['ConnectionList'] = _CONNECTIONLIST
+DESCRIPTOR.message_types_by_name['ConnectionEvent'] = _CONNECTIONEVENT
+DESCRIPTOR.message_types_by_name['EndPointId'] = _ENDPOINTID
+DESCRIPTOR.message_types_by_name['EndPoint'] = _ENDPOINT
+DESCRIPTOR.message_types_by_name['ConfigRule'] = _CONFIGRULE
+DESCRIPTOR.message_types_by_name['Constraint'] = _CONSTRAINT
+DESCRIPTOR.message_types_by_name['TeraFlowController'] = _TERAFLOWCONTROLLER
+DESCRIPTOR.message_types_by_name['AuthenticationResult'] = _AUTHENTICATIONRESULT
+DESCRIPTOR.enum_types_by_name['EventTypeEnum'] = _EVENTTYPEENUM
+DESCRIPTOR.enum_types_by_name['DeviceDriverEnum'] = _DEVICEDRIVERENUM
+DESCRIPTOR.enum_types_by_name['DeviceOperationalStatusEnum'] = _DEVICEOPERATIONALSTATUSENUM
+DESCRIPTOR.enum_types_by_name['ServiceTypeEnum'] = _SERVICETYPEENUM
+DESCRIPTOR.enum_types_by_name['ServiceStatusEnum'] = _SERVICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['SliceStatusEnum'] = _SLICESTATUSENUM
+DESCRIPTOR.enum_types_by_name['ConfigActionEnum'] = _CONFIGACTIONENUM
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+Empty = _reflection.GeneratedProtocolMessageType('Empty', (_message.Message,), {
+  'DESCRIPTOR' : _EMPTY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Empty)
+  })
+_sym_db.RegisterMessage(Empty)
+
+Uuid = _reflection.GeneratedProtocolMessageType('Uuid', (_message.Message,), {
+  'DESCRIPTOR' : _UUID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Uuid)
+  })
+_sym_db.RegisterMessage(Uuid)
+
+Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), {
+  'DESCRIPTOR' : _EVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Event)
+  })
+_sym_db.RegisterMessage(Event)
+
+ContextId = _reflection.GeneratedProtocolMessageType('ContextId', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextId)
+  })
+_sym_db.RegisterMessage(ContextId)
+
+Context = _reflection.GeneratedProtocolMessageType('Context', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Context)
+  })
+_sym_db.RegisterMessage(Context)
+
+ContextIdList = _reflection.GeneratedProtocolMessageType('ContextIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextIdList)
+  })
+_sym_db.RegisterMessage(ContextIdList)
+
+ContextList = _reflection.GeneratedProtocolMessageType('ContextList', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextList)
+  })
+_sym_db.RegisterMessage(ContextList)
+
+ContextEvent = _reflection.GeneratedProtocolMessageType('ContextEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONTEXTEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ContextEvent)
+  })
+_sym_db.RegisterMessage(ContextEvent)
+
+TopologyId = _reflection.GeneratedProtocolMessageType('TopologyId', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyId)
+  })
+_sym_db.RegisterMessage(TopologyId)
+
+Topology = _reflection.GeneratedProtocolMessageType('Topology', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGY,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Topology)
+  })
+_sym_db.RegisterMessage(Topology)
+
+TopologyIdList = _reflection.GeneratedProtocolMessageType('TopologyIdList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyIdList)
+  })
+_sym_db.RegisterMessage(TopologyIdList)
+
+TopologyList = _reflection.GeneratedProtocolMessageType('TopologyList', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyList)
+  })
+_sym_db.RegisterMessage(TopologyList)
+
+TopologyEvent = _reflection.GeneratedProtocolMessageType('TopologyEvent', (_message.Message,), {
+  'DESCRIPTOR' : _TOPOLOGYEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TopologyEvent)
+  })
+_sym_db.RegisterMessage(TopologyEvent)
+
+DeviceId = _reflection.GeneratedProtocolMessageType('DeviceId', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceId)
+  })
+_sym_db.RegisterMessage(DeviceId)
+
+Device = _reflection.GeneratedProtocolMessageType('Device', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Device)
+  })
+_sym_db.RegisterMessage(Device)
+
+DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceConfig)
+  })
+_sym_db.RegisterMessage(DeviceConfig)
+
+DeviceIdList = _reflection.GeneratedProtocolMessageType('DeviceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceIdList)
+  })
+_sym_db.RegisterMessage(DeviceIdList)
+
+DeviceList = _reflection.GeneratedProtocolMessageType('DeviceList', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceList)
+  })
+_sym_db.RegisterMessage(DeviceList)
+
+DeviceEvent = _reflection.GeneratedProtocolMessageType('DeviceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _DEVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.DeviceEvent)
+  })
+_sym_db.RegisterMessage(DeviceEvent)
+
+LinkId = _reflection.GeneratedProtocolMessageType('LinkId', (_message.Message,), {
+  'DESCRIPTOR' : _LINKID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkId)
+  })
+_sym_db.RegisterMessage(LinkId)
+
+Link = _reflection.GeneratedProtocolMessageType('Link', (_message.Message,), {
+  'DESCRIPTOR' : _LINK,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Link)
+  })
+_sym_db.RegisterMessage(Link)
+
+LinkIdList = _reflection.GeneratedProtocolMessageType('LinkIdList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkIdList)
+  })
+_sym_db.RegisterMessage(LinkIdList)
+
+LinkList = _reflection.GeneratedProtocolMessageType('LinkList', (_message.Message,), {
+  'DESCRIPTOR' : _LINKLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkList)
+  })
+_sym_db.RegisterMessage(LinkList)
+
+LinkEvent = _reflection.GeneratedProtocolMessageType('LinkEvent', (_message.Message,), {
+  'DESCRIPTOR' : _LINKEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.LinkEvent)
+  })
+_sym_db.RegisterMessage(LinkEvent)
+
+ServiceId = _reflection.GeneratedProtocolMessageType('ServiceId', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceId)
+  })
+_sym_db.RegisterMessage(ServiceId)
+
+Service = _reflection.GeneratedProtocolMessageType('Service', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Service)
+  })
+_sym_db.RegisterMessage(Service)
+
+ServiceStatus = _reflection.GeneratedProtocolMessageType('ServiceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceStatus)
+  })
+_sym_db.RegisterMessage(ServiceStatus)
+
+ServiceConfig = _reflection.GeneratedProtocolMessageType('ServiceConfig', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICECONFIG,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceConfig)
+  })
+_sym_db.RegisterMessage(ServiceConfig)
+
+ServiceIdList = _reflection.GeneratedProtocolMessageType('ServiceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceIdList)
+  })
+_sym_db.RegisterMessage(ServiceIdList)
+
+ServiceList = _reflection.GeneratedProtocolMessageType('ServiceList', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceList)
+  })
+_sym_db.RegisterMessage(ServiceList)
+
+ServiceEvent = _reflection.GeneratedProtocolMessageType('ServiceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SERVICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ServiceEvent)
+  })
+_sym_db.RegisterMessage(ServiceEvent)
+
+SliceId = _reflection.GeneratedProtocolMessageType('SliceId', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceId)
+  })
+_sym_db.RegisterMessage(SliceId)
+
+Slice = _reflection.GeneratedProtocolMessageType('Slice', (_message.Message,), {
+  'DESCRIPTOR' : _SLICE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Slice)
+  })
+_sym_db.RegisterMessage(Slice)
+
+SliceStatus = _reflection.GeneratedProtocolMessageType('SliceStatus', (_message.Message,), {
+  'DESCRIPTOR' : _SLICESTATUS,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceStatus)
+  })
+_sym_db.RegisterMessage(SliceStatus)
+
+SliceIdList = _reflection.GeneratedProtocolMessageType('SliceIdList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceIdList)
+  })
+_sym_db.RegisterMessage(SliceIdList)
+
+SliceList = _reflection.GeneratedProtocolMessageType('SliceList', (_message.Message,), {
+  'DESCRIPTOR' : _SLICELIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceList)
+  })
+_sym_db.RegisterMessage(SliceList)
+
+SliceEvent = _reflection.GeneratedProtocolMessageType('SliceEvent', (_message.Message,), {
+  'DESCRIPTOR' : _SLICEEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.SliceEvent)
+  })
+_sym_db.RegisterMessage(SliceEvent)
+
+ConnectionId = _reflection.GeneratedProtocolMessageType('ConnectionId', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionId)
+  })
+_sym_db.RegisterMessage(ConnectionId)
+
+Connection = _reflection.GeneratedProtocolMessageType('Connection', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTION,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Connection)
+  })
+_sym_db.RegisterMessage(Connection)
+
+ConnectionIdList = _reflection.GeneratedProtocolMessageType('ConnectionIdList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONIDLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionIdList)
+  })
+_sym_db.RegisterMessage(ConnectionIdList)
+
+ConnectionList = _reflection.GeneratedProtocolMessageType('ConnectionList', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONLIST,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionList)
+  })
+_sym_db.RegisterMessage(ConnectionList)
+
+ConnectionEvent = _reflection.GeneratedProtocolMessageType('ConnectionEvent', (_message.Message,), {
+  'DESCRIPTOR' : _CONNECTIONEVENT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConnectionEvent)
+  })
+_sym_db.RegisterMessage(ConnectionEvent)
+
+EndPointId = _reflection.GeneratedProtocolMessageType('EndPointId', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINTID,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPointId)
+  })
+_sym_db.RegisterMessage(EndPointId)
+
+EndPoint = _reflection.GeneratedProtocolMessageType('EndPoint', (_message.Message,), {
+  'DESCRIPTOR' : _ENDPOINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.EndPoint)
+  })
+_sym_db.RegisterMessage(EndPoint)
+
+ConfigRule = _reflection.GeneratedProtocolMessageType('ConfigRule', (_message.Message,), {
+  'DESCRIPTOR' : _CONFIGRULE,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.ConfigRule)
+  })
+_sym_db.RegisterMessage(ConfigRule)
+
+Constraint = _reflection.GeneratedProtocolMessageType('Constraint', (_message.Message,), {
+  'DESCRIPTOR' : _CONSTRAINT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.Constraint)
+  })
+_sym_db.RegisterMessage(Constraint)
+
+TeraFlowController = _reflection.GeneratedProtocolMessageType('TeraFlowController', (_message.Message,), {
+  'DESCRIPTOR' : _TERAFLOWCONTROLLER,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.TeraFlowController)
+  })
+_sym_db.RegisterMessage(TeraFlowController)
+
+AuthenticationResult = _reflection.GeneratedProtocolMessageType('AuthenticationResult', (_message.Message,), {
+  'DESCRIPTOR' : _AUTHENTICATIONRESULT,
+  '__module__' : 'context_pb2'
+  # @@protoc_insertion_point(class_scope:context.AuthenticationResult)
+  })
+_sym_db.RegisterMessage(AuthenticationResult)
+
+
+
+_CONTEXTSERVICE = _descriptor.ServiceDescriptor(
+  name='ContextService',
+  full_name='context.ContextService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=5273,
+  serialized_end=7688,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='ListContextIds',
+    full_name='context.ContextService.ListContextIds',
+    index=0,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListContexts',
+    full_name='context.ContextService.ListContexts',
+    index=1,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContext',
+    full_name='context.ContextService.GetContext',
+    index=2,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_CONTEXT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetContext',
+    full_name='context.ContextService.SetContext',
+    index=3,
+    containing_service=None,
+    input_type=_CONTEXT,
+    output_type=_CONTEXTID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveContext',
+    full_name='context.ContextService.RemoveContext',
+    index=4,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetContextEvents',
+    full_name='context.ContextService.GetContextEvents',
+    index=5,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONTEXTEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologyIds',
+    full_name='context.ContextService.ListTopologyIds',
+    index=6,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListTopologies',
+    full_name='context.ContextService.ListTopologies',
+    index=7,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_TOPOLOGYLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopology',
+    full_name='context.ContextService.GetTopology',
+    index=8,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_TOPOLOGY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetTopology',
+    full_name='context.ContextService.SetTopology',
+    index=9,
+    containing_service=None,
+    input_type=_TOPOLOGY,
+    output_type=_TOPOLOGYID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveTopology',
+    full_name='context.ContextService.RemoveTopology',
+    index=10,
+    containing_service=None,
+    input_type=_TOPOLOGYID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetTopologyEvents',
+    full_name='context.ContextService.GetTopologyEvents',
+    index=11,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_TOPOLOGYEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDeviceIds',
+    full_name='context.ContextService.ListDeviceIds',
+    index=12,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListDevices',
+    full_name='context.ContextService.ListDevices',
+    index=13,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDevice',
+    full_name='context.ContextService.GetDevice',
+    index=14,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_DEVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetDevice',
+    full_name='context.ContextService.SetDevice',
+    index=15,
+    containing_service=None,
+    input_type=_DEVICE,
+    output_type=_DEVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveDevice',
+    full_name='context.ContextService.RemoveDevice',
+    index=16,
+    containing_service=None,
+    input_type=_DEVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDeviceEvents',
+    full_name='context.ContextService.GetDeviceEvents',
+    index=17,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_DEVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinkIds',
+    full_name='context.ContextService.ListLinkIds',
+    index=18,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListLinks',
+    full_name='context.ContextService.ListLinks',
+    index=19,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLink',
+    full_name='context.ContextService.GetLink',
+    index=20,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_LINK,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetLink',
+    full_name='context.ContextService.SetLink',
+    index=21,
+    containing_service=None,
+    input_type=_LINK,
+    output_type=_LINKID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveLink',
+    full_name='context.ContextService.RemoveLink',
+    index=22,
+    containing_service=None,
+    input_type=_LINKID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetLinkEvents',
+    full_name='context.ContextService.GetLinkEvents',
+    index=23,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_LINKEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServiceIds',
+    full_name='context.ContextService.ListServiceIds',
+    index=24,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListServices',
+    full_name='context.ContextService.ListServices',
+    index=25,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SERVICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetService',
+    full_name='context.ContextService.GetService',
+    index=26,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_SERVICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetService',
+    full_name='context.ContextService.SetService',
+    index=27,
+    containing_service=None,
+    input_type=_SERVICE,
+    output_type=_SERVICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveService',
+    full_name='context.ContextService.RemoveService',
+    index=28,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetServiceEvents',
+    full_name='context.ContextService.GetServiceEvents',
+    index=29,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SERVICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSliceIds',
+    full_name='context.ContextService.ListSliceIds',
+    index=30,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICEIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListSlices',
+    full_name='context.ContextService.ListSlices',
+    index=31,
+    containing_service=None,
+    input_type=_CONTEXTID,
+    output_type=_SLICELIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSlice',
+    full_name='context.ContextService.GetSlice',
+    index=32,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_SLICE,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetSlice',
+    full_name='context.ContextService.SetSlice',
+    index=33,
+    containing_service=None,
+    input_type=_SLICE,
+    output_type=_SLICEID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveSlice',
+    full_name='context.ContextService.RemoveSlice',
+    index=34,
+    containing_service=None,
+    input_type=_SLICEID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetSliceEvents',
+    full_name='context.ContextService.GetSliceEvents',
+    index=35,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_SLICEEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnectionIds',
+    full_name='context.ContextService.ListConnectionIds',
+    index=36,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONIDLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='ListConnections',
+    full_name='context.ContextService.ListConnections',
+    index=37,
+    containing_service=None,
+    input_type=_SERVICEID,
+    output_type=_CONNECTIONLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnection',
+    full_name='context.ContextService.GetConnection',
+    index=38,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_CONNECTION,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SetConnection',
+    full_name='context.ContextService.SetConnection',
+    index=39,
+    containing_service=None,
+    input_type=_CONNECTION,
+    output_type=_CONNECTIONID,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='RemoveConnection',
+    full_name='context.ContextService.RemoveConnection',
+    index=40,
+    containing_service=None,
+    input_type=_CONNECTIONID,
+    output_type=_EMPTY,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetConnectionEvents',
+    full_name='context.ContextService.GetConnectionEvents',
+    index=41,
+    containing_service=None,
+    input_type=_EMPTY,
+    output_type=_CONNECTIONEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_CONTEXTSERVICE)
+
+DESCRIPTOR.services_by_name['ContextService'] = _CONTEXTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/dlt/connector/proto/dlt_pb2.py b/src/dlt/connector/proto/dlt_pb2.py
new file mode 100644
index 000000000..098eb374a
--- /dev/null
+++ b/src/dlt/connector/proto/dlt_pb2.py
@@ -0,0 +1,638 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: dlt.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+from . import context_pb2 as context__pb2
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='dlt.proto',
+  package='dlt',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\tdlt.proto\x12\x03\x64lt\x1a\rcontext.proto\"{\n\x0b\x44ltRecordId\x12\"\n\x0b\x64omain_uuid\x18\x01 \x01(\x0b\x32\r.context.Uuid\x12$\n\x04type\x18\x02 \x01(\x0e\x32\x16.dlt.DltRecordTypeEnum\x12\"\n\x0brecord_uuid\x18\x03 \x01(\x0b\x32\r.context.Uuid\"s\n\tDltRecord\x12#\n\trecord_id\x18\x01 \x01(\x0b\x32\x10.dlt.DltRecordId\x12.\n\toperation\x18\x02 \x01(\x0e\x32\x1b.dlt.DltRecordOperationEnum\x12\x11\n\tdata_json\x18\x03 \x01(\t\"m\n\x15\x44ltRecordSubscription\x12$\n\x04type\x18\x01 \x03(\x0e\x32\x16.dlt.DltRecordTypeEnum\x12.\n\toperation\x18\x02 \x03(\x0e\x32\x1b.dlt.DltRecordOperationEnum\"T\n\x0e\x44ltRecordEvent\x12\x1d\n\x05\x65vent\x18\x01 \x01(\x0b\x32\x0e.context.Event\x12#\n\trecord_id\x18\x02 \x01(\x0b\x32\x10.dlt.DltRecordId\"w\n\x0f\x44ltRecordStatus\x12#\n\trecord_id\x18\x01 \x01(\x0b\x32\x10.dlt.DltRecordId\x12(\n\x06status\x18\x02 \x01(\x0e\x32\x18.dlt.DltRecordStatusEnum\x12\x15\n\rerror_message\x18\x03 \x01(\t\"d\n\rDltPeerStatus\x12/\n\ncontroller\x18\x01 \x01(\x0b\x32\x1b.context.TeraFlowController\x12\"\n\x06status\x18\x02 \x01(\x0e\x32\x12.dlt.DltStatusEnum\"6\n\x11\x44ltPeerStatusList\x12!\n\x05peers\x18\x01 \x03(\x0b\x32\x12.dlt.DltPeerStatus*\xcd\x01\n\x11\x44ltRecordTypeEnum\x12\x1b\n\x17\x44LTRECORDTYPE_UNDEFINED\x10\x00\x12\x19\n\x15\x44LTRECORDTYPE_CONTEXT\x10\x01\x12\x1a\n\x16\x44LTRECORDTYPE_TOPOLOGY\x10\x02\x12\x18\n\x14\x44LTRECORDTYPE_DEVICE\x10\x03\x12\x16\n\x12\x44LTRECORDTYPE_LINK\x10\x04\x12\x19\n\x15\x44LTRECORDTYPE_SERVICE\x10\x05\x12\x17\n\x13\x44LTRECORDTYPE_SLICE\x10\x06*\x94\x01\n\x16\x44ltRecordOperationEnum\x12 \n\x1c\x44LTRECORDOPERATION_UNDEFINED\x10\x00\x12\x1a\n\x16\x44LTRECORDOPERATION_ADD\x10\x01\x12\x1d\n\x19\x44LTRECORDOPERATION_UPDATE\x10\x02\x12\x1d\n\x19\x44LTRECORDOPERATION_DELETE\x10\x03*o\n\x13\x44ltRecordStatusEnum\x12\x1d\n\x19\x44LTRECORDSTATUS_UNDEFINED\x10\x00\x12\x1d\n\x19\x44LTRECORDSTATUS_SUCCEEDED\x10\x01\x12\x1a\n\x16\x44LTRECORDSTATUS_FAILED\x10\x02*\x8e\x01\n\rDltStatusEnum\x12\x17\n\x13\x44LTSTATUS_UNDEFINED\x10\x00\x12\x1a\n\x16\x44LTSTATUS_NOTAVAILABLE\x10\x01\x12\x19\n\x15\x44LTSTATUS_INITIALIZED\x10\x02\x12\x17\n\x13\x44LTSTATUS_AVAILABLE\x10\x03\x12\x14\n\x10\x44LTSTATUS_DEINIT\x10\x04\x32\xb8\x02\n\nDltService\x12\x35\n\x0bRecordToDlt\x12\x0e.dlt.DltRecord\x1a\x14.dlt.DltRecordStatus\"\x00\x12\x30\n\nGetFromDlt\x12\x10.dlt.DltRecordId\x1a\x0e.dlt.DltRecord\"\x00\x12\x45\n\x0eSubscribeToDlt\x12\x1a.dlt.DltRecordSubscription\x1a\x13.dlt.DltRecordEvent\"\x00\x30\x01\x12\x41\n\x0cGetDltStatus\x12\x1b.context.TeraFlowController\x1a\x12.dlt.DltPeerStatus\"\x00\x12\x37\n\x0bGetDltPeers\x12\x0e.context.Empty\x1a\x16.dlt.DltPeerStatusList\"\x00\x62\x06proto3'
+  ,
+  dependencies=[context__pb2.DESCRIPTOR,])
+
+_DLTRECORDTYPEENUM = _descriptor.EnumDescriptor(
+  name='DltRecordTypeEnum',
+  full_name='dlt.DltRecordTypeEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDTYPE_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDTYPE_CONTEXT', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDTYPE_TOPOLOGY', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDTYPE_DEVICE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDTYPE_LINK', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDTYPE_SERVICE', index=5, number=5,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDTYPE_SLICE', index=6, number=6,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=752,
+  serialized_end=957,
+)
+_sym_db.RegisterEnumDescriptor(_DLTRECORDTYPEENUM)
+
+DltRecordTypeEnum = enum_type_wrapper.EnumTypeWrapper(_DLTRECORDTYPEENUM)
+_DLTRECORDOPERATIONENUM = _descriptor.EnumDescriptor(
+  name='DltRecordOperationEnum',
+  full_name='dlt.DltRecordOperationEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDOPERATION_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDOPERATION_ADD', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDOPERATION_UPDATE', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDOPERATION_DELETE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=960,
+  serialized_end=1108,
+)
+_sym_db.RegisterEnumDescriptor(_DLTRECORDOPERATIONENUM)
+
+DltRecordOperationEnum = enum_type_wrapper.EnumTypeWrapper(_DLTRECORDOPERATIONENUM)
+_DLTRECORDSTATUSENUM = _descriptor.EnumDescriptor(
+  name='DltRecordStatusEnum',
+  full_name='dlt.DltRecordStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDSTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDSTATUS_SUCCEEDED', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTRECORDSTATUS_FAILED', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=1110,
+  serialized_end=1221,
+)
+_sym_db.RegisterEnumDescriptor(_DLTRECORDSTATUSENUM)
+
+DltRecordStatusEnum = enum_type_wrapper.EnumTypeWrapper(_DLTRECORDSTATUSENUM)
+_DLTSTATUSENUM = _descriptor.EnumDescriptor(
+  name='DltStatusEnum',
+  full_name='dlt.DltStatusEnum',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='DLTSTATUS_UNDEFINED', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTSTATUS_NOTAVAILABLE', index=1, number=1,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTSTATUS_INITIALIZED', index=2, number=2,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTSTATUS_AVAILABLE', index=3, number=3,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='DLTSTATUS_DEINIT', index=4, number=4,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=1224,
+  serialized_end=1366,
+)
+_sym_db.RegisterEnumDescriptor(_DLTSTATUSENUM)
+
+DltStatusEnum = enum_type_wrapper.EnumTypeWrapper(_DLTSTATUSENUM)
+DLTRECORDTYPE_UNDEFINED = 0
+DLTRECORDTYPE_CONTEXT = 1
+DLTRECORDTYPE_TOPOLOGY = 2
+DLTRECORDTYPE_DEVICE = 3
+DLTRECORDTYPE_LINK = 4
+DLTRECORDTYPE_SERVICE = 5
+DLTRECORDTYPE_SLICE = 6
+DLTRECORDOPERATION_UNDEFINED = 0
+DLTRECORDOPERATION_ADD = 1
+DLTRECORDOPERATION_UPDATE = 2
+DLTRECORDOPERATION_DELETE = 3
+DLTRECORDSTATUS_UNDEFINED = 0
+DLTRECORDSTATUS_SUCCEEDED = 1
+DLTRECORDSTATUS_FAILED = 2
+DLTSTATUS_UNDEFINED = 0
+DLTSTATUS_NOTAVAILABLE = 1
+DLTSTATUS_INITIALIZED = 2
+DLTSTATUS_AVAILABLE = 3
+DLTSTATUS_DEINIT = 4
+
+
+
+_DLTRECORDID = _descriptor.Descriptor(
+  name='DltRecordId',
+  full_name='dlt.DltRecordId',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='domain_uuid', full_name='dlt.DltRecordId.domain_uuid', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='type', full_name='dlt.DltRecordId.type', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='record_uuid', full_name='dlt.DltRecordId.record_uuid', index=2,
+      number=3, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=33,
+  serialized_end=156,
+)
+
+
+_DLTRECORD = _descriptor.Descriptor(
+  name='DltRecord',
+  full_name='dlt.DltRecord',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='record_id', full_name='dlt.DltRecord.record_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='operation', full_name='dlt.DltRecord.operation', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='data_json', full_name='dlt.DltRecord.data_json', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=158,
+  serialized_end=273,
+)
+
+
+_DLTRECORDSUBSCRIPTION = _descriptor.Descriptor(
+  name='DltRecordSubscription',
+  full_name='dlt.DltRecordSubscription',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='type', full_name='dlt.DltRecordSubscription.type', index=0,
+      number=1, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='operation', full_name='dlt.DltRecordSubscription.operation', index=1,
+      number=2, type=14, cpp_type=8, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=275,
+  serialized_end=384,
+)
+
+
+_DLTRECORDEVENT = _descriptor.Descriptor(
+  name='DltRecordEvent',
+  full_name='dlt.DltRecordEvent',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='event', full_name='dlt.DltRecordEvent.event', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='record_id', full_name='dlt.DltRecordEvent.record_id', index=1,
+      number=2, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=386,
+  serialized_end=470,
+)
+
+
+_DLTRECORDSTATUS = _descriptor.Descriptor(
+  name='DltRecordStatus',
+  full_name='dlt.DltRecordStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='record_id', full_name='dlt.DltRecordStatus.record_id', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='dlt.DltRecordStatus.status', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='error_message', full_name='dlt.DltRecordStatus.error_message', index=2,
+      number=3, type=9, cpp_type=9, label=1,
+      has_default_value=False, default_value=b"".decode('utf-8'),
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=472,
+  serialized_end=591,
+)
+
+
+_DLTPEERSTATUS = _descriptor.Descriptor(
+  name='DltPeerStatus',
+  full_name='dlt.DltPeerStatus',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='controller', full_name='dlt.DltPeerStatus.controller', index=0,
+      number=1, type=11, cpp_type=10, label=1,
+      has_default_value=False, default_value=None,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+    _descriptor.FieldDescriptor(
+      name='status', full_name='dlt.DltPeerStatus.status', index=1,
+      number=2, type=14, cpp_type=8, label=1,
+      has_default_value=False, default_value=0,
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=593,
+  serialized_end=693,
+)
+
+
+_DLTPEERSTATUSLIST = _descriptor.Descriptor(
+  name='DltPeerStatusList',
+  full_name='dlt.DltPeerStatusList',
+  filename=None,
+  file=DESCRIPTOR,
+  containing_type=None,
+  create_key=_descriptor._internal_create_key,
+  fields=[
+    _descriptor.FieldDescriptor(
+      name='peers', full_name='dlt.DltPeerStatusList.peers', index=0,
+      number=1, type=11, cpp_type=10, label=3,
+      has_default_value=False, default_value=[],
+      message_type=None, enum_type=None, containing_type=None,
+      is_extension=False, extension_scope=None,
+      serialized_options=None, file=DESCRIPTOR,  create_key=_descriptor._internal_create_key),
+  ],
+  extensions=[
+  ],
+  nested_types=[],
+  enum_types=[
+  ],
+  serialized_options=None,
+  is_extendable=False,
+  syntax='proto3',
+  extension_ranges=[],
+  oneofs=[
+  ],
+  serialized_start=695,
+  serialized_end=749,
+)
+
+_DLTRECORDID.fields_by_name['domain_uuid'].message_type = context__pb2._UUID
+_DLTRECORDID.fields_by_name['type'].enum_type = _DLTRECORDTYPEENUM
+_DLTRECORDID.fields_by_name['record_uuid'].message_type = context__pb2._UUID
+_DLTRECORD.fields_by_name['record_id'].message_type = _DLTRECORDID
+_DLTRECORD.fields_by_name['operation'].enum_type = _DLTRECORDOPERATIONENUM
+_DLTRECORDSUBSCRIPTION.fields_by_name['type'].enum_type = _DLTRECORDTYPEENUM
+_DLTRECORDSUBSCRIPTION.fields_by_name['operation'].enum_type = _DLTRECORDOPERATIONENUM
+_DLTRECORDEVENT.fields_by_name['event'].message_type = context__pb2._EVENT
+_DLTRECORDEVENT.fields_by_name['record_id'].message_type = _DLTRECORDID
+_DLTRECORDSTATUS.fields_by_name['record_id'].message_type = _DLTRECORDID
+_DLTRECORDSTATUS.fields_by_name['status'].enum_type = _DLTRECORDSTATUSENUM
+_DLTPEERSTATUS.fields_by_name['controller'].message_type = context__pb2._TERAFLOWCONTROLLER
+_DLTPEERSTATUS.fields_by_name['status'].enum_type = _DLTSTATUSENUM
+_DLTPEERSTATUSLIST.fields_by_name['peers'].message_type = _DLTPEERSTATUS
+DESCRIPTOR.message_types_by_name['DltRecordId'] = _DLTRECORDID
+DESCRIPTOR.message_types_by_name['DltRecord'] = _DLTRECORD
+DESCRIPTOR.message_types_by_name['DltRecordSubscription'] = _DLTRECORDSUBSCRIPTION
+DESCRIPTOR.message_types_by_name['DltRecordEvent'] = _DLTRECORDEVENT
+DESCRIPTOR.message_types_by_name['DltRecordStatus'] = _DLTRECORDSTATUS
+DESCRIPTOR.message_types_by_name['DltPeerStatus'] = _DLTPEERSTATUS
+DESCRIPTOR.message_types_by_name['DltPeerStatusList'] = _DLTPEERSTATUSLIST
+DESCRIPTOR.enum_types_by_name['DltRecordTypeEnum'] = _DLTRECORDTYPEENUM
+DESCRIPTOR.enum_types_by_name['DltRecordOperationEnum'] = _DLTRECORDOPERATIONENUM
+DESCRIPTOR.enum_types_by_name['DltRecordStatusEnum'] = _DLTRECORDSTATUSENUM
+DESCRIPTOR.enum_types_by_name['DltStatusEnum'] = _DLTSTATUSENUM
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+DltRecordId = _reflection.GeneratedProtocolMessageType('DltRecordId', (_message.Message,), {
+  'DESCRIPTOR' : _DLTRECORDID,
+  '__module__' : 'dlt_pb2'
+  # @@protoc_insertion_point(class_scope:dlt.DltRecordId)
+  })
+_sym_db.RegisterMessage(DltRecordId)
+
+DltRecord = _reflection.GeneratedProtocolMessageType('DltRecord', (_message.Message,), {
+  'DESCRIPTOR' : _DLTRECORD,
+  '__module__' : 'dlt_pb2'
+  # @@protoc_insertion_point(class_scope:dlt.DltRecord)
+  })
+_sym_db.RegisterMessage(DltRecord)
+
+DltRecordSubscription = _reflection.GeneratedProtocolMessageType('DltRecordSubscription', (_message.Message,), {
+  'DESCRIPTOR' : _DLTRECORDSUBSCRIPTION,
+  '__module__' : 'dlt_pb2'
+  # @@protoc_insertion_point(class_scope:dlt.DltRecordSubscription)
+  })
+_sym_db.RegisterMessage(DltRecordSubscription)
+
+DltRecordEvent = _reflection.GeneratedProtocolMessageType('DltRecordEvent', (_message.Message,), {
+  'DESCRIPTOR' : _DLTRECORDEVENT,
+  '__module__' : 'dlt_pb2'
+  # @@protoc_insertion_point(class_scope:dlt.DltRecordEvent)
+  })
+_sym_db.RegisterMessage(DltRecordEvent)
+
+DltRecordStatus = _reflection.GeneratedProtocolMessageType('DltRecordStatus', (_message.Message,), {
+  'DESCRIPTOR' : _DLTRECORDSTATUS,
+  '__module__' : 'dlt_pb2'
+  # @@protoc_insertion_point(class_scope:dlt.DltRecordStatus)
+  })
+_sym_db.RegisterMessage(DltRecordStatus)
+
+DltPeerStatus = _reflection.GeneratedProtocolMessageType('DltPeerStatus', (_message.Message,), {
+  'DESCRIPTOR' : _DLTPEERSTATUS,
+  '__module__' : 'dlt_pb2'
+  # @@protoc_insertion_point(class_scope:dlt.DltPeerStatus)
+  })
+_sym_db.RegisterMessage(DltPeerStatus)
+
+DltPeerStatusList = _reflection.GeneratedProtocolMessageType('DltPeerStatusList', (_message.Message,), {
+  'DESCRIPTOR' : _DLTPEERSTATUSLIST,
+  '__module__' : 'dlt_pb2'
+  # @@protoc_insertion_point(class_scope:dlt.DltPeerStatusList)
+  })
+_sym_db.RegisterMessage(DltPeerStatusList)
+
+
+
+_DLTSERVICE = _descriptor.ServiceDescriptor(
+  name='DltService',
+  full_name='dlt.DltService',
+  file=DESCRIPTOR,
+  index=0,
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_start=1369,
+  serialized_end=1681,
+  methods=[
+  _descriptor.MethodDescriptor(
+    name='RecordToDlt',
+    full_name='dlt.DltService.RecordToDlt',
+    index=0,
+    containing_service=None,
+    input_type=_DLTRECORD,
+    output_type=_DLTRECORDSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetFromDlt',
+    full_name='dlt.DltService.GetFromDlt',
+    index=1,
+    containing_service=None,
+    input_type=_DLTRECORDID,
+    output_type=_DLTRECORD,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='SubscribeToDlt',
+    full_name='dlt.DltService.SubscribeToDlt',
+    index=2,
+    containing_service=None,
+    input_type=_DLTRECORDSUBSCRIPTION,
+    output_type=_DLTRECORDEVENT,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDltStatus',
+    full_name='dlt.DltService.GetDltStatus',
+    index=3,
+    containing_service=None,
+    input_type=context__pb2._TERAFLOWCONTROLLER,
+    output_type=_DLTPEERSTATUS,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+  _descriptor.MethodDescriptor(
+    name='GetDltPeers',
+    full_name='dlt.DltService.GetDltPeers',
+    index=4,
+    containing_service=None,
+    input_type=context__pb2._EMPTY,
+    output_type=_DLTPEERSTATUSLIST,
+    serialized_options=None,
+    create_key=_descriptor._internal_create_key,
+  ),
+])
+_sym_db.RegisterServiceDescriptor(_DLTSERVICE)
+
+DESCRIPTOR.services_by_name['DltService'] = _DLTSERVICE
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/dlt/connector/proto/dlt_pb2_grpc.py b/src/dlt/connector/proto/dlt_pb2_grpc.py
new file mode 100644
index 000000000..7419d5428
--- /dev/null
+++ b/src/dlt/connector/proto/dlt_pb2_grpc.py
@@ -0,0 +1,199 @@
+# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT!
+"""Client and server classes corresponding to protobuf-defined services."""
+import grpc
+
+from . import context_pb2 as context__pb2
+from . import dlt_pb2 as dlt__pb2
+
+
+class DltServiceStub(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def __init__(self, channel):
+        """Constructor.
+
+        Args:
+            channel: A grpc.Channel.
+        """
+        self.RecordToDlt = channel.unary_unary(
+                '/dlt.DltService/RecordToDlt',
+                request_serializer=dlt__pb2.DltRecord.SerializeToString,
+                response_deserializer=dlt__pb2.DltRecordStatus.FromString,
+                )
+        self.GetFromDlt = channel.unary_unary(
+                '/dlt.DltService/GetFromDlt',
+                request_serializer=dlt__pb2.DltRecordId.SerializeToString,
+                response_deserializer=dlt__pb2.DltRecord.FromString,
+                )
+        self.SubscribeToDlt = channel.unary_stream(
+                '/dlt.DltService/SubscribeToDlt',
+                request_serializer=dlt__pb2.DltRecordSubscription.SerializeToString,
+                response_deserializer=dlt__pb2.DltRecordEvent.FromString,
+                )
+        self.GetDltStatus = channel.unary_unary(
+                '/dlt.DltService/GetDltStatus',
+                request_serializer=context__pb2.TeraFlowController.SerializeToString,
+                response_deserializer=dlt__pb2.DltPeerStatus.FromString,
+                )
+        self.GetDltPeers = channel.unary_unary(
+                '/dlt.DltService/GetDltPeers',
+                request_serializer=context__pb2.Empty.SerializeToString,
+                response_deserializer=dlt__pb2.DltPeerStatusList.FromString,
+                )
+
+
+class DltServiceServicer(object):
+    """Missing associated documentation comment in .proto file."""
+
+    def RecordToDlt(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetFromDlt(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def SubscribeToDlt(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetDltStatus(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+    def GetDltPeers(self, request, context):
+        """Missing associated documentation comment in .proto file."""
+        context.set_code(grpc.StatusCode.UNIMPLEMENTED)
+        context.set_details('Method not implemented!')
+        raise NotImplementedError('Method not implemented!')
+
+
+def add_DltServiceServicer_to_server(servicer, server):
+    rpc_method_handlers = {
+            'RecordToDlt': grpc.unary_unary_rpc_method_handler(
+                    servicer.RecordToDlt,
+                    request_deserializer=dlt__pb2.DltRecord.FromString,
+                    response_serializer=dlt__pb2.DltRecordStatus.SerializeToString,
+            ),
+            'GetFromDlt': grpc.unary_unary_rpc_method_handler(
+                    servicer.GetFromDlt,
+                    request_deserializer=dlt__pb2.DltRecordId.FromString,
+                    response_serializer=dlt__pb2.DltRecord.SerializeToString,
+            ),
+            'SubscribeToDlt': grpc.unary_stream_rpc_method_handler(
+                    servicer.SubscribeToDlt,
+                    request_deserializer=dlt__pb2.DltRecordSubscription.FromString,
+                    response_serializer=dlt__pb2.DltRecordEvent.SerializeToString,
+            ),
+            'GetDltStatus': grpc.unary_unary_rpc_method_handler(
+                    servicer.GetDltStatus,
+                    request_deserializer=context__pb2.TeraFlowController.FromString,
+                    response_serializer=dlt__pb2.DltPeerStatus.SerializeToString,
+            ),
+            'GetDltPeers': grpc.unary_unary_rpc_method_handler(
+                    servicer.GetDltPeers,
+                    request_deserializer=context__pb2.Empty.FromString,
+                    response_serializer=dlt__pb2.DltPeerStatusList.SerializeToString,
+            ),
+    }
+    generic_handler = grpc.method_handlers_generic_handler(
+            'dlt.DltService', rpc_method_handlers)
+    server.add_generic_rpc_handlers((generic_handler,))
+
+
+ # This class is part of an EXPERIMENTAL API.
+class DltService(object):
+    """Missing associated documentation comment in .proto file."""
+
+    @staticmethod
+    def RecordToDlt(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/dlt.DltService/RecordToDlt',
+            dlt__pb2.DltRecord.SerializeToString,
+            dlt__pb2.DltRecordStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetFromDlt(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/dlt.DltService/GetFromDlt',
+            dlt__pb2.DltRecordId.SerializeToString,
+            dlt__pb2.DltRecord.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def SubscribeToDlt(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_stream(request, target, '/dlt.DltService/SubscribeToDlt',
+            dlt__pb2.DltRecordSubscription.SerializeToString,
+            dlt__pb2.DltRecordEvent.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetDltStatus(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/dlt.DltService/GetDltStatus',
+            context__pb2.TeraFlowController.SerializeToString,
+            dlt__pb2.DltPeerStatus.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
+
+    @staticmethod
+    def GetDltPeers(request,
+            target,
+            options=(),
+            channel_credentials=None,
+            call_credentials=None,
+            insecure=False,
+            compression=None,
+            wait_for_ready=None,
+            timeout=None,
+            metadata=None):
+        return grpc.experimental.unary_unary(request, target, '/dlt.DltService/GetDltPeers',
+            context__pb2.Empty.SerializeToString,
+            dlt__pb2.DltPeerStatusList.FromString,
+            options, channel_credentials,
+            insecure, call_credentials, compression, wait_for_ready, timeout, metadata)
diff --git a/src/dlt/connector/proto/kpi_sample_types_pb2.py b/src/dlt/connector/proto/kpi_sample_types_pb2.py
new file mode 100644
index 000000000..ea7fd2f82
--- /dev/null
+++ b/src/dlt/connector/proto/kpi_sample_types_pb2.py
@@ -0,0 +1,78 @@
+# -*- coding: utf-8 -*-
+# Generated by the protocol buffer compiler.  DO NOT EDIT!
+# source: kpi_sample_types.proto
+"""Generated protocol buffer code."""
+from google.protobuf.internal import enum_type_wrapper
+from google.protobuf import descriptor as _descriptor
+from google.protobuf import message as _message
+from google.protobuf import reflection as _reflection
+from google.protobuf import symbol_database as _symbol_database
+# @@protoc_insertion_point(imports)
+
+_sym_db = _symbol_database.Default()
+
+
+
+
+DESCRIPTOR = _descriptor.FileDescriptor(
+  name='kpi_sample_types.proto',
+  package='kpi_sample_types',
+  syntax='proto3',
+  serialized_options=None,
+  create_key=_descriptor._internal_create_key,
+  serialized_pb=b'\n\x16kpi_sample_types.proto\x12\x10kpi_sample_types*\xbe\x01\n\rKpiSampleType\x12\x19\n\x15KPISAMPLETYPE_UNKNOWN\x10\x00\x12%\n!KPISAMPLETYPE_PACKETS_TRANSMITTED\x10\x65\x12\"\n\x1eKPISAMPLETYPE_PACKETS_RECEIVED\x10\x66\x12$\n\x1fKPISAMPLETYPE_BYTES_TRANSMITTED\x10\xc9\x01\x12!\n\x1cKPISAMPLETYPE_BYTES_RECEIVED\x10\xca\x01\x62\x06proto3'
+)
+
+_KPISAMPLETYPE = _descriptor.EnumDescriptor(
+  name='KpiSampleType',
+  full_name='kpi_sample_types.KpiSampleType',
+  filename=None,
+  file=DESCRIPTOR,
+  create_key=_descriptor._internal_create_key,
+  values=[
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_UNKNOWN', index=0, number=0,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_TRANSMITTED', index=1, number=101,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_PACKETS_RECEIVED', index=2, number=102,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_TRANSMITTED', index=3, number=201,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+    _descriptor.EnumValueDescriptor(
+      name='KPISAMPLETYPE_BYTES_RECEIVED', index=4, number=202,
+      serialized_options=None,
+      type=None,
+      create_key=_descriptor._internal_create_key),
+  ],
+  containing_type=None,
+  serialized_options=None,
+  serialized_start=45,
+  serialized_end=235,
+)
+_sym_db.RegisterEnumDescriptor(_KPISAMPLETYPE)
+
+KpiSampleType = enum_type_wrapper.EnumTypeWrapper(_KPISAMPLETYPE)
+KPISAMPLETYPE_UNKNOWN = 0
+KPISAMPLETYPE_PACKETS_TRANSMITTED = 101
+KPISAMPLETYPE_PACKETS_RECEIVED = 102
+KPISAMPLETYPE_BYTES_TRANSMITTED = 201
+KPISAMPLETYPE_BYTES_RECEIVED = 202
+
+
+DESCRIPTOR.enum_types_by_name['KpiSampleType'] = _KPISAMPLETYPE
+_sym_db.RegisterFileDescriptor(DESCRIPTOR)
+
+
+# @@protoc_insertion_point(module_scope)
diff --git a/src/dlt/connector/service/__init__.py b/src/dlt/connector/service/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/dlt/connector/service/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/dlt/connector/tests/__init__.py b/src/dlt/connector/tests/__init__.py
new file mode 100644
index 000000000..70a332512
--- /dev/null
+++ b/src/dlt/connector/tests/__init__.py
@@ -0,0 +1,14 @@
+# Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
diff --git a/src/dlt/.gitignore b/src/dlt/gateway/.gitignore
similarity index 100%
rename from src/dlt/.gitignore
rename to src/dlt/gateway/.gitignore
diff --git a/src/dlt/README.md b/src/dlt/gateway/README.md
similarity index 100%
rename from src/dlt/README.md
rename to src/dlt/gateway/README.md
diff --git a/src/dlt/build.gradle.kts b/src/dlt/gateway/build.gradle.kts
similarity index 100%
rename from src/dlt/build.gradle.kts
rename to src/dlt/gateway/build.gradle.kts
diff --git a/src/dlt/config/ca.org1.example.com-cert.pem b/src/dlt/gateway/config/ca.org1.example.com-cert.pem
similarity index 100%
rename from src/dlt/config/ca.org1.example.com-cert.pem
rename to src/dlt/gateway/config/ca.org1.example.com-cert.pem
diff --git a/src/dlt/config/connection-org1.json b/src/dlt/gateway/config/connection-org1.json
similarity index 100%
rename from src/dlt/config/connection-org1.json
rename to src/dlt/gateway/config/connection-org1.json
diff --git a/src/dlt/gradle.properties b/src/dlt/gateway/gradle.properties
similarity index 100%
rename from src/dlt/gradle.properties
rename to src/dlt/gateway/gradle.properties
diff --git a/src/dlt/gradle/wrapper/gradle-wrapper.jar b/src/dlt/gateway/gradle/wrapper/gradle-wrapper.jar
similarity index 100%
rename from src/dlt/gradle/wrapper/gradle-wrapper.jar
rename to src/dlt/gateway/gradle/wrapper/gradle-wrapper.jar
diff --git a/src/dlt/gradle/wrapper/gradle-wrapper.properties b/src/dlt/gateway/gradle/wrapper/gradle-wrapper.properties
similarity index 100%
rename from src/dlt/gradle/wrapper/gradle-wrapper.properties
rename to src/dlt/gateway/gradle/wrapper/gradle-wrapper.properties
diff --git a/src/dlt/gradlew b/src/dlt/gateway/gradlew
similarity index 100%
rename from src/dlt/gradlew
rename to src/dlt/gateway/gradlew
diff --git a/src/dlt/gradlew.bat b/src/dlt/gateway/gradlew.bat
similarity index 100%
rename from src/dlt/gradlew.bat
rename to src/dlt/gateway/gradlew.bat
diff --git a/src/dlt/settings.gradle.kts b/src/dlt/gateway/settings.gradle.kts
similarity index 100%
rename from src/dlt/settings.gradle.kts
rename to src/dlt/gateway/settings.gradle.kts
diff --git a/src/dlt/src/main/kotlin/Main.kt b/src/dlt/gateway/src/main/kotlin/Main.kt
similarity index 100%
rename from src/dlt/src/main/kotlin/Main.kt
rename to src/dlt/gateway/src/main/kotlin/Main.kt
diff --git a/src/dlt/src/main/kotlin/fabric/ConnectGateway.kt b/src/dlt/gateway/src/main/kotlin/fabric/ConnectGateway.kt
similarity index 100%
rename from src/dlt/src/main/kotlin/fabric/ConnectGateway.kt
rename to src/dlt/gateway/src/main/kotlin/fabric/ConnectGateway.kt
diff --git a/src/dlt/src/main/kotlin/fabric/EnrollAdmin.kt b/src/dlt/gateway/src/main/kotlin/fabric/EnrollAdmin.kt
similarity index 100%
rename from src/dlt/src/main/kotlin/fabric/EnrollAdmin.kt
rename to src/dlt/gateway/src/main/kotlin/fabric/EnrollAdmin.kt
diff --git a/src/dlt/src/main/kotlin/fabric/FabricConnector.kt b/src/dlt/gateway/src/main/kotlin/fabric/FabricConnector.kt
similarity index 100%
rename from src/dlt/src/main/kotlin/fabric/FabricConnector.kt
rename to src/dlt/gateway/src/main/kotlin/fabric/FabricConnector.kt
diff --git a/src/dlt/src/main/kotlin/fabric/RegisterUser.kt b/src/dlt/gateway/src/main/kotlin/fabric/RegisterUser.kt
similarity index 100%
rename from src/dlt/src/main/kotlin/fabric/RegisterUser.kt
rename to src/dlt/gateway/src/main/kotlin/fabric/RegisterUser.kt
diff --git a/src/dlt/src/main/kotlin/http/Server.kt b/src/dlt/gateway/src/main/kotlin/http/Server.kt
similarity index 100%
rename from src/dlt/src/main/kotlin/http/Server.kt
rename to src/dlt/gateway/src/main/kotlin/http/Server.kt
diff --git a/src/dlt/src/main/kotlin/proto/Config.proto b/src/dlt/gateway/src/main/kotlin/proto/Config.proto
similarity index 100%
rename from src/dlt/src/main/kotlin/proto/Config.proto
rename to src/dlt/gateway/src/main/kotlin/proto/Config.proto
-- 
GitLab


From 745de758457529668eb1aa9930a8b079e52b76b2 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Tue, 5 Jul 2022 17:36:13 +0300
Subject: [PATCH 57/60] chore(policy): update application.yml

---
 src/policy/src/main/resources/application.yml | 17 +++++++++++++++++
 src/policy/target/kubernetes/kubernetes.yml   | 18 ++++++++++++------
 2 files changed, 29 insertions(+), 6 deletions(-)

diff --git a/src/policy/src/main/resources/application.yml b/src/policy/src/main/resources/application.yml
index 2e09b2302..0f6f45931 100644
--- a/src/policy/src/main/resources/application.yml
+++ b/src/policy/src/main/resources/application.yml
@@ -19,6 +19,17 @@ quarkus:
     server:
       port: 9999
       enable-reflection-service: true
+    clients:
+      context:
+        host: ${quarkus.kubernetes.env.vars.context-service-host}
+        port: 1010
+      monitoring:
+        host: ${quarkus.kubernetes.env.vars.monitoring-service-host}
+        port: 7070
+      service:
+        host: ${quarkus.kubernetes.env.vars.service-service-host}
+        port: 3030
+
   http:
     port: 8080
 
@@ -46,3 +57,9 @@ quarkus:
       grpc-server:
         host-port: 9999
         container-port: 9999
+    env:
+      vars:
+        context-service-host: "contextservice"
+        monitoring-service-host: "monitoringservice"
+        service-service-host: "serviceservice"
+
diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml
index 3625e9d85..462e59696 100644
--- a/src/policy/target/kubernetes/kubernetes.yml
+++ b/src/policy/target/kubernetes/kubernetes.yml
@@ -3,8 +3,8 @@ apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 54b760b9045db694a08b0f291f52b28aa4d8c5d2
-    app.quarkus.io/build-timestamp: 2022-05-23 - 13:57:10 +0000
+    app.quarkus.io/commit-id: 2aa29b383ec7bf12dc985729978210239ea8a726
+    app.quarkus.io/build-timestamp: 2022-07-07 - 10:19:44 +0000
   labels:
     app.kubernetes.io/name: policyservice
     app: policyservice
@@ -25,8 +25,8 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 54b760b9045db694a08b0f291f52b28aa4d8c5d2
-    app.quarkus.io/build-timestamp: 2022-05-23 - 13:57:10 +0000
+    app.quarkus.io/commit-id: 2aa29b383ec7bf12dc985729978210239ea8a726
+    app.quarkus.io/build-timestamp: 2022-07-07 - 10:19:44 +0000
   labels:
     app: policyservice
     app.kubernetes.io/name: policyservice
@@ -39,8 +39,8 @@ spec:
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: 54b760b9045db694a08b0f291f52b28aa4d8c5d2
-        app.quarkus.io/build-timestamp: 2022-05-23 - 13:57:10 +0000
+        app.quarkus.io/commit-id: 2aa29b383ec7bf12dc985729978210239ea8a726
+        app.quarkus.io/build-timestamp: 2022-07-07 - 10:19:44 +0000
       labels:
         app: policyservice
         app.kubernetes.io/name: policyservice
@@ -51,6 +51,12 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
+            - name: MONITORING_SERVICE_HOST
+              value: monitoringservice
+            - name: SERVICE_SERVICE_HOST
+              value: serviceservice
+            - name: CONTEXT_SERVICE_HOST
+              value: contextservice
           image: registry.gitlab.com/teraflow-h2020/controller/policy:0.1.0
           imagePullPolicy: Always
           livenessProbe:
-- 
GitLab


From 2bfdc93b379692a7d96bd04ef3c9db364676947c Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Mon, 11 Jul 2022 16:59:43 +0300
Subject: [PATCH 58/60] refactor(policy): update policy.proto

PolicyAdd rpc replaced by PolicyAddService & PolicyAddDevice
---
 proto/policy.proto                            |   97 +-
 .../eu/teraflow/policy/PolicyGatewayImpl.java |   60 +-
 .../eu/teraflow/policy/PolicyService.java     |    7 +-
 .../eu/teraflow/policy/PolicyServiceImpl.java |   10 +-
 .../eu/teraflow/policy/model/PolicyRule.java  |  111 -
 .../policy/model/PolicyRuleEvent.java         |   37 -
 .../teraflow/policy/model/PolicyRuleType.java |   22 -
 .../eu/teraflow/policy/PolicyServiceTest.java |  147 +-
 .../grpc/policy/MutinyPolicyServiceGrpc.java  |  152 +-
 .../generated-sources/grpc/policy/Policy.java | 8294 +++++++++++------
 .../grpc/policy/PolicyService.java            |   16 +-
 .../grpc/policy/PolicyServiceBean.java        |   36 +-
 .../grpc/policy/PolicyServiceClient.java      |   28 +-
 .../grpc/policy/PolicyServiceGrpc.java        |  460 +-
 src/policy/target/kubernetes/kubernetes.yml   |   16 +-
 15 files changed, 6117 insertions(+), 3376 deletions(-)
 delete mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java
 delete mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java
 delete mode 100644 src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java

diff --git a/proto/policy.proto b/proto/policy.proto
index 0887ae955..9e67b7764 100644
--- a/proto/policy.proto
+++ b/proto/policy.proto
@@ -20,23 +20,28 @@ import "policy-condition.proto";
 import "policy-action.proto";
 
 service PolicyService {
-  rpc PolicyAdd (PolicyRule) returns (PolicyRuleState) {}
-  rpc PolicyUpdate (PolicyRule) returns (PolicyRuleState) {}
-  rpc PolicyDelete (PolicyRule) returns (PolicyRuleState) {}
-  rpc GetPolicy (PolicyRuleId) returns (PolicyRule) {}
-  rpc GetPolicyByDeviceId (context.DeviceId) returns (PolicyRuleList) {}
-  rpc GetPolicyByServiceId (context.ServiceId) returns (PolicyRuleList) {}
+  rpc PolicyAddService (PolicyRuleService) returns (PolicyRuleState) {}
+  rpc PolicyAddDevice (PolicyRuleDevice) returns (PolicyRuleState) {}
+  rpc PolicyUpdateService (PolicyRuleService) returns (PolicyRuleState) {}
+  rpc PolicyUpdateDevice (PolicyRuleDevice) returns (PolicyRuleState) {}
+  rpc PolicyDelete (PolicyRuleId) returns (PolicyRuleState) {}
+  rpc GetPolicyService (PolicyRuleId) returns (PolicyRuleService) {}
+  rpc GetPolicyDevice (PolicyRuleId) returns (PolicyRuleDevice) {}
+  rpc GetPolicyByServiceId (context.ServiceId) returns (PolicyRuleServiceList) {}
 }
 
 enum RuleState {
-  POLICY_INACTIVE = 0;    // Rule is currently inactive
-  POLICY_PLANNED = 1;     // Rule installation planned
-  POLICY_ACTIVE = 2;      // Rule is currently active
-}
-
-enum PolicyRuleType {
-  POLICYTYPE_DEVICE = 0;  // Device-level
-  POLICYTYPE_NETWORK = 1; // Network-wide
+  POLICY_UNDEFINED = 0;     // Undefined rule state
+  POLICY_FAILED = 1;        // Rule failed
+  POLICY_INSERTED = 2;      // Rule is just inserted
+  POLICY_VALIDATED = 3;     // Rule content is correct
+  POLICY_PROVISIONED = 4;   // Rule subscribed to Monitoring
+  POLICY_ACTIVE = 5;        // Rule is currently active (alarm is just thrown by Monitoring)
+  POLICY_ENFORCED = 6;      // Rule action is successfully enforced
+  POLICY_INEFFECTIVE = 7;   // The applied rule action did not work as expected
+  POLICY_EFFECTIVE = 8;     // The applied rule action did work as expected
+  POLICY_UPDATED = 9;       // Operator requires a policy to change
+  POLICY_REMOVED = 10;      // Operator requires to remove a policy
 }
 
 message PolicyRuleId {
@@ -44,39 +49,51 @@ message PolicyRuleId {
 }
 
 message PolicyRuleState {
-  context.Uuid policyRuleId = 1;
-  RuleState policyRuleState = 2;
+  RuleState policyRuleState = 1;
 }
 
-// IETF draft: Framework for Use of ECA (Event Condition Action) in Network Self Management
-//     Source: https://datatracker.ietf.org/doc/draft-bwd-netmod-eca-framework/
-// Event
-message PolicyRuleEvent {
-  context.Event event = 1;
+// Basic policy rule attributes
+message PolicyRuleBasic {
+  PolicyRuleId policyRuleId = 1;
+  optional PolicyRuleState policyRuleState = 2;
+  uint32 priority = 3;
+
+  // Event-Condition-Action (ECA) model
+  repeated PolicyRuleCondition conditionList = 4;  // When these policy conditions are met, an event is automatically thrown
+  BooleanOperator booleanOperator = 5;             // Evaluation operator to be used
+  repeated PolicyRuleAction actionList = 6;        // One or more actions should be applied
 }
 
-// Policy rule partially complies with IETF’s:
-//     RFC 3060: https://datatracker.ietf.org/doc/html/rfc3060
-//     RFC 3460: https://datatracker.ietf.org/doc/html/rfc3460
-// Enhanced with a policy rule event according to the ECA model
-message PolicyRule {
+// Service-oriented policy rule
+message PolicyRuleService {
   // Basic policy rule attributes
-  PolicyRuleId policyRuleId = 1;
-  PolicyRuleType policyRuleType = 2;
-  uint32 priority = 3;
+  PolicyRuleBasic policyRuleBasic = 1;
 
-  // Event-Condition-Action model
-  PolicyRuleEvent event = 4;                         // A single event triggers the policy
-  repeated PolicyRuleCondition conditionList = 5;    // One or more conditions must be met
-  BooleanOperator booleanOperator = 6;               // Evaluation operator to be used
-  repeated PolicyRuleAction actionList = 7;          // One or more actions should be applied
+  // Affected service and (some of) its device(s)
+  context.ServiceId serviceId = 2;
+  repeated context.DeviceId deviceList = 3;  // List of devices this service is traversing (not exhaustive)
+}
+
+// Device-oriented policy rule
+message PolicyRuleDevice {
+  // Basic policy rule attributes
+  PolicyRuleBasic policyRuleBasic = 1;
+
+  // Affected device(s)
+  repeated context.DeviceId deviceList = 2;
+}
+
+// A list of policy rule IDs
+message PolicyRuleIdList {
+  repeated PolicyRuleId policyRuleIdList = 1;
+}
 
-  // Affected service and devices
-  context.ServiceId serviceId = 8;
-  repeated context.DeviceId deviceList = 9;
+// A list of service-oriented policy rules
+message PolicyRuleServiceList {
+  repeated PolicyRuleService policyRuleServiceList = 1;
 }
 
-// A list of policy rules
-message PolicyRuleList {
-  repeated PolicyRule policyRuleList = 1;
+// A list of device-oriented policy rules
+message PolicyRuleDeviceList {
+  repeated PolicyRuleDevice policyRuleDeviceList = 1;
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java
index b95271708..642fabcba 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyGatewayImpl.java
@@ -16,11 +16,18 @@
 
 package eu.teraflow.policy;
 
-import context.ContextOuterClass;
+import context.ContextOuterClass.ServiceId;
 import io.quarkus.grpc.GrpcService;
 import io.smallrye.mutiny.Uni;
 import javax.inject.Inject;
 import policy.Policy;
+import policy.Policy.PolicyRuleBasic;
+import policy.Policy.PolicyRuleDevice;
+import policy.Policy.PolicyRuleId;
+import policy.Policy.PolicyRuleService;
+import policy.Policy.PolicyRuleServiceList;
+import policy.Policy.PolicyRuleState;
+import policy.Policy.RuleState;
 
 @GrpcService
 public class PolicyGatewayImpl implements PolicyGateway {
@@ -33,50 +40,77 @@ public class PolicyGatewayImpl implements PolicyGateway {
     }
 
     @Override
-    public Uni<Policy.PolicyRuleState> policyAdd(Policy.PolicyRule request) {
+    public Uni<PolicyRuleState> policyAddService(PolicyRuleService request) {
         return Uni.createFrom()
                 .item(
                         () ->
                                 Policy.PolicyRuleState.newBuilder()
-                                        .setPolicyRuleId(request.getPolicyRuleId().getUuid())
+                                        .setPolicyRuleState(
+                                                request.getPolicyRuleBasic().getPolicyRuleState().getPolicyRuleState())
                                         .build());
     }
 
     @Override
-    public Uni<Policy.PolicyRuleState> policyUpdate(Policy.PolicyRule request) {
+    public Uni<PolicyRuleState> policyAddDevice(PolicyRuleDevice request) {
         return Uni.createFrom()
                 .item(
                         () ->
                                 Policy.PolicyRuleState.newBuilder()
-                                        .setPolicyRuleId(request.getPolicyRuleId().getUuid())
+                                        .setPolicyRuleState(
+                                                request.getPolicyRuleBasic().getPolicyRuleState().getPolicyRuleState())
                                         .build());
     }
 
     @Override
-    public Uni<Policy.PolicyRuleState> policyDelete(Policy.PolicyRule request) {
+    public Uni<PolicyRuleState> policyUpdateService(PolicyRuleService request) {
         return Uni.createFrom()
                 .item(
                         () ->
                                 Policy.PolicyRuleState.newBuilder()
-                                        .setPolicyRuleId(request.getPolicyRuleId().getUuid())
+                                        .setPolicyRuleState(
+                                                request.getPolicyRuleBasic().getPolicyRuleState().getPolicyRuleState())
                                         .build());
     }
 
     @Override
-    public Uni<Policy.PolicyRule> getPolicy(Policy.PolicyRuleId request) {
+    public Uni<PolicyRuleState> policyUpdateDevice(PolicyRuleDevice request) {
         return Uni.createFrom()
-                .item(() -> Policy.PolicyRule.newBuilder().setPolicyRuleId(request).build());
+                .item(
+                        () ->
+                                Policy.PolicyRuleState.newBuilder()
+                                        .setPolicyRuleState(
+                                                request.getPolicyRuleBasic().getPolicyRuleState().getPolicyRuleState())
+                                        .build());
     }
 
     @Override
-    public Uni<Policy.PolicyRuleList> getPolicyByDeviceId(ContextOuterClass.DeviceId request) {
+    public Uni<PolicyRuleState> policyDelete(PolicyRuleId request) {
+        return Uni.createFrom()
+                .item(
+                        () ->
+                                Policy.PolicyRuleState.newBuilder()
+                                        .setPolicyRuleState(RuleState.POLICY_REMOVED)
+                                        .build());
+    }
+
+    @Override
+    public Uni<PolicyRuleService> getPolicyService(PolicyRuleId request) {
+        final var policyRuleBasic = PolicyRuleBasic.newBuilder().setPolicyRuleId(request).build();
 
-        return Uni.createFrom().item(() -> Policy.PolicyRuleList.newBuilder().build());
+        return Uni.createFrom()
+                .item(() -> PolicyRuleService.newBuilder().setPolicyRuleBasic(policyRuleBasic).build());
     }
 
     @Override
-    public Uni<Policy.PolicyRuleList> getPolicyByServiceId(ContextOuterClass.ServiceId request) {
+    public Uni<PolicyRuleDevice> getPolicyDevice(PolicyRuleId request) {
+        final var policyRuleBasic = PolicyRuleBasic.newBuilder().setPolicyRuleId(request).build();
 
-        return Uni.createFrom().item(() -> Policy.PolicyRuleList.newBuilder().build());
+        return Uni.createFrom()
+                .item(() -> PolicyRuleDevice.newBuilder().setPolicyRuleBasic(policyRuleBasic).build());
+    }
+
+    @Override
+    public Uni<PolicyRuleServiceList> getPolicyByServiceId(ServiceId request) {
+        return Uni.createFrom().item(() -> Policy.PolicyRuleServiceList.newBuilder().build());
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyService.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyService.java
index d20775cc1..14ffbb41e 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/PolicyService.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyService.java
@@ -16,11 +16,14 @@
 
 package eu.teraflow.policy;
 
-import eu.teraflow.policy.model.PolicyRule;
 import eu.teraflow.policy.model.PolicyRuleState;
 import io.smallrye.mutiny.Uni;
+import policy.Policy.PolicyRuleDevice;
+import policy.Policy.PolicyRuleService;
 
 public interface PolicyService {
 
-    Uni<PolicyRuleState> addPolicy(PolicyRule policyRule);
+    Uni<PolicyRuleState> addPolicyService(PolicyRuleService policyRuleService);
+
+    Uni<PolicyRuleState> addPolicyDevice(PolicyRuleDevice policyRuleDevice);
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java b/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java
index d8025d080..c9645c5e3 100644
--- a/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java
+++ b/src/policy/src/main/java/eu/teraflow/policy/PolicyServiceImpl.java
@@ -16,19 +16,25 @@
 
 package eu.teraflow.policy;
 
-import eu.teraflow.policy.model.PolicyRule;
 import eu.teraflow.policy.model.PolicyRuleState;
 import io.smallrye.mutiny.Uni;
 import javax.enterprise.context.ApplicationScoped;
 import org.jboss.logging.Logger;
+import policy.Policy.PolicyRuleDevice;
+import policy.Policy.PolicyRuleService;
 
 @ApplicationScoped
 public class PolicyServiceImpl implements PolicyService {
 
     private static final Logger LOGGER = Logger.getLogger(PolicyServiceImpl.class);
 
-    public Uni<PolicyRuleState> addPolicy(PolicyRule policyRule) {
+    @Override
+    public Uni<PolicyRuleState> addPolicyService(PolicyRuleService policyRuleService) {
+        return null;
+    }
 
+    @Override
+    public Uni<PolicyRuleState> addPolicyDevice(PolicyRuleDevice policyRuleDevice) {
         return null;
     }
 }
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java
deleted file mode 100644
index 18dbfa73d..000000000
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRule.java
+++ /dev/null
@@ -1,111 +0,0 @@
-/*
-* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package eu.teraflow.policy.model;
-
-import eu.teraflow.policy.context.model.ServiceId;
-import java.util.List;
-import java.util.stream.Collectors;
-
-public class PolicyRule {
-
-    private final String policyRuleId;
-    private final PolicyRuleType policyRuleType;
-    private final int priority;
-    private final PolicyRuleEvent event;
-    private final List<PolicyRuleCondition> policyRuleConditions;
-    private final BooleanOperator booleanOperator;
-    private final List<PolicyRuleAction> policyRuleActions;
-    private final ServiceId serviceId;
-    private final List<String> deviceIds;
-
-    public PolicyRule(
-            String policyRuleId,
-            PolicyRuleType policyRuleType,
-            int priority,
-            PolicyRuleEvent event,
-            List<PolicyRuleCondition> policyRuleConditions,
-            BooleanOperator booleanOperator,
-            List<PolicyRuleAction> policyRuleActions,
-            ServiceId serviceId,
-            List<String> deviceIds) {
-        this.policyRuleId = policyRuleId;
-        this.policyRuleType = policyRuleType;
-        this.priority = priority;
-        this.event = event;
-        this.policyRuleConditions = policyRuleConditions;
-        this.booleanOperator = booleanOperator;
-        this.policyRuleActions = policyRuleActions;
-        this.serviceId = serviceId;
-        this.deviceIds = deviceIds;
-    }
-
-    public String getPolicyRuleId() {
-        return policyRuleId;
-    }
-
-    public PolicyRuleType getPolicyRuleType() {
-        return policyRuleType;
-    }
-
-    public int getPriority() {
-        return priority;
-    }
-
-    public PolicyRuleEvent getEvent() {
-        return event;
-    }
-
-    public List<PolicyRuleCondition> getPolicyRuleConditions() {
-        return policyRuleConditions;
-    }
-
-    public BooleanOperator getBooleanOperator() {
-        return booleanOperator;
-    }
-
-    public List<PolicyRuleAction> getPolicyRuleActions() {
-        return policyRuleActions;
-    }
-
-    public ServiceId getServiceId() {
-        return serviceId;
-    }
-
-    public List<String> getDeviceIds() {
-        return deviceIds;
-    }
-
-    @Override
-    public String toString() {
-        return String.format(
-                "%s:{policyRuleId:\"%s\", policyRuleType:\"%s\", priority:%d, %s, [%s], booleanOperator:\"%s\", [%s], %s, [%s]}",
-                getClass().getSimpleName(),
-                policyRuleId,
-                policyRuleType.toString(),
-                priority,
-                event,
-                toString(policyRuleConditions),
-                booleanOperator.toString(),
-                toString(policyRuleActions),
-                serviceId,
-                toString(deviceIds));
-    }
-
-    private <T> String toString(List<T> list) {
-        return list.stream().map(T::toString).collect(Collectors.joining(", "));
-    }
-}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java
deleted file mode 100644
index 412c6c718..000000000
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleEvent.java
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package eu.teraflow.policy.model;
-
-import eu.teraflow.policy.context.model.Event;
-
-public class PolicyRuleEvent {
-
-    private final Event event;
-
-    public PolicyRuleEvent(Event event) {
-        this.event = event;
-    }
-
-    public Event getEvent() {
-        return event;
-    }
-
-    @Override
-    public String toString() {
-        return String.format("%s:{%s}", getClass().getSimpleName(), event);
-    }
-}
diff --git a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java b/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java
deleted file mode 100644
index 321220176..000000000
--- a/src/policy/src/main/java/eu/teraflow/policy/model/PolicyRuleType.java
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
-* Copyright 2021-2023 H2020 TeraFlow (https://www.teraflow-h2020.eu/)
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*/
-
-package eu.teraflow.policy.model;
-
-public enum PolicyRuleType {
-    POLICYTYPE_DEVICE,
-    POLICYTYPE_NETWORK
-}
diff --git a/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java b/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java
index 47a5502d1..bf1af532f 100644
--- a/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java
+++ b/src/policy/src/test/java/eu/teraflow/policy/PolicyServiceTest.java
@@ -29,6 +29,8 @@ import java.util.concurrent.TimeoutException;
 import org.jboss.logging.Logger;
 import org.junit.jupiter.api.Test;
 import policy.Policy;
+import policy.Policy.PolicyRuleBasic;
+import policy.Policy.RuleState;
 import policy.PolicyService;
 
 @QuarkusTest
@@ -38,47 +40,89 @@ class PolicyServiceTest {
     @GrpcClient PolicyService client;
 
     @Test
-    void shouldAddPolicy() throws ExecutionException, InterruptedException, TimeoutException {
+    void shouldAddPolicyService() throws ExecutionException, InterruptedException, TimeoutException {
         CompletableFuture<String> message = new CompletableFuture<>();
 
-        final var uuid =
-                ContextOuterClass.Uuid.newBuilder()
-                        .setUuid(UUID.fromString("0f14d0ab-9608-7862-a9e4-5ed26688389b").toString())
-                        .build();
-        final var policyRuleId = Policy.PolicyRuleId.newBuilder().setUuid(uuid).build();
-        final var policyRule = Policy.PolicyRule.newBuilder().setPolicyRuleId(policyRuleId).build();
+        final var expectedPolicyRuleState =
+                Policy.PolicyRuleState.newBuilder().setPolicyRuleState(RuleState.POLICY_ACTIVE).build();
+
+        final var policyRuleBasic =
+                PolicyRuleBasic.newBuilder().setPolicyRuleState(expectedPolicyRuleState).build();
+        final var policyRuleService =
+                Policy.PolicyRuleService.newBuilder().setPolicyRuleBasic(policyRuleBasic).build();
 
         client
-                .policyAdd(policyRule)
+                .policyAddService(policyRuleService)
                 .subscribe()
-                .with(
-                        policyRuleState -> {
-                            LOGGER.infof("Adding policy: %s", policyRuleState.getPolicyRuleId().getUuid());
-                            message.complete(policyRuleState.getPolicyRuleId().getUuid());
-                        });
-        assertThat(message.get(5, TimeUnit.SECONDS)).isEqualTo(policyRuleId.getUuid().getUuid());
+                .with(policyRuleState -> message.complete(policyRuleState.getPolicyRuleState().toString()));
+
+        assertThat(message.get(5, TimeUnit.SECONDS))
+                .isEqualTo(expectedPolicyRuleState.getPolicyRuleState().toString());
     }
 
     @Test
-    void shouldUpdatePolicy() throws ExecutionException, InterruptedException, TimeoutException {
+    void shouldAddPolicyDevice() throws ExecutionException, InterruptedException, TimeoutException {
         CompletableFuture<String> message = new CompletableFuture<>();
 
-        final var uuid =
-                ContextOuterClass.Uuid.newBuilder()
-                        .setUuid(UUID.fromString("0f14d0ab-9608-7862-a9e4-5ed26688389b").toString())
-                        .build();
-        final var policyRuleId = Policy.PolicyRuleId.newBuilder().setUuid(uuid).build();
-        final var policyRule = Policy.PolicyRule.newBuilder().setPolicyRuleId(policyRuleId).build();
+        final var expectedPolicyRuleState =
+                Policy.PolicyRuleState.newBuilder().setPolicyRuleState(RuleState.POLICY_EFFECTIVE).build();
+
+        final var policyRuleBasic =
+                PolicyRuleBasic.newBuilder().setPolicyRuleState(expectedPolicyRuleState).build();
+        final var policyRuleDevice =
+                Policy.PolicyRuleDevice.newBuilder().setPolicyRuleBasic(policyRuleBasic).build();
 
         client
-                .policyUpdate(policyRule)
+                .policyAddDevice(policyRuleDevice)
                 .subscribe()
-                .with(
-                        policyRuleState -> {
-                            LOGGER.infof("Updating policy: %s", policyRuleState.getPolicyRuleId().getUuid());
-                            message.complete(policyRuleState.getPolicyRuleId().getUuid());
-                        });
-        assertThat(message.get(5, TimeUnit.SECONDS)).isEqualTo(policyRuleId.getUuid().getUuid());
+                .with(policyRuleState -> message.complete(policyRuleState.getPolicyRuleState().toString()));
+
+        assertThat(message.get(5, TimeUnit.SECONDS))
+                .isEqualTo(expectedPolicyRuleState.getPolicyRuleState().toString());
+    }
+
+    @Test
+    void shouldUpdatePolicyService()
+            throws ExecutionException, InterruptedException, TimeoutException {
+        CompletableFuture<String> message = new CompletableFuture<>();
+
+        final var expectedPolicyRuleState =
+                Policy.PolicyRuleState.newBuilder().setPolicyRuleState(RuleState.POLICY_ENFORCED).build();
+
+        final var policyRuleBasic =
+                PolicyRuleBasic.newBuilder().setPolicyRuleState(expectedPolicyRuleState).build();
+        final var policyRuleService =
+                Policy.PolicyRuleService.newBuilder().setPolicyRuleBasic(policyRuleBasic).build();
+
+        client
+                .policyUpdateService(policyRuleService)
+                .subscribe()
+                .with(policyRuleState -> message.complete(policyRuleState.getPolicyRuleState().toString()));
+
+        assertThat(message.get(5, TimeUnit.SECONDS))
+                .isEqualTo(expectedPolicyRuleState.getPolicyRuleState().toString());
+    }
+
+    @Test
+    void shouldUpdatePolicyDevice()
+            throws ExecutionException, InterruptedException, TimeoutException {
+        CompletableFuture<String> message = new CompletableFuture<>();
+
+        final var expectedPolicyRuleState =
+                Policy.PolicyRuleState.newBuilder().setPolicyRuleState(RuleState.POLICY_ENFORCED).build();
+
+        final var policyRuleBasic =
+                PolicyRuleBasic.newBuilder().setPolicyRuleState(expectedPolicyRuleState).build();
+        final var policyRuleDevice =
+                Policy.PolicyRuleDevice.newBuilder().setPolicyRuleBasic(policyRuleBasic).build();
+
+        client
+                .policyUpdateDevice(policyRuleDevice)
+                .subscribe()
+                .with(policyRuleState -> message.complete(policyRuleState.getPolicyRuleState().toString()));
+
+        assertThat(message.get(5, TimeUnit.SECONDS))
+                .isEqualTo(expectedPolicyRuleState.getPolicyRuleState().toString());
     }
 
     @Test
@@ -90,21 +134,21 @@ class PolicyServiceTest {
                         .setUuid(UUID.fromString("0f14d0ab-9608-7862-a9e4-5ed26688389b").toString())
                         .build();
         final var policyRuleId = Policy.PolicyRuleId.newBuilder().setUuid(uuid).build();
-        final var policyRule = Policy.PolicyRule.newBuilder().setPolicyRuleId(policyRuleId).build();
+
+        final var expectedPolicyRuleState =
+                Policy.PolicyRuleState.newBuilder().setPolicyRuleState(RuleState.POLICY_REMOVED).build();
 
         client
-                .policyDelete(policyRule)
+                .policyDelete(policyRuleId)
                 .subscribe()
-                .with(
-                        policyRuleState -> {
-                            LOGGER.infof("Deleting policy: %s", policyRuleState.getPolicyRuleId().getUuid());
-                            message.complete(policyRuleState.getPolicyRuleId().getUuid());
-                        });
-        assertThat(message.get(5, TimeUnit.SECONDS)).isEqualTo(policyRuleId.getUuid().getUuid());
+                .with(policyRuleState -> message.complete(policyRuleState.getPolicyRuleState().toString()));
+
+        assertThat(message.get(5, TimeUnit.SECONDS))
+                .isEqualTo(expectedPolicyRuleState.getPolicyRuleState().toString());
     }
 
     @Test
-    void shouldGetPolicy() throws ExecutionException, InterruptedException, TimeoutException {
+    void shouldGetPolicyService() throws ExecutionException, InterruptedException, TimeoutException {
         CompletableFuture<String> message = new CompletableFuture<>();
 
         final var uuid =
@@ -114,40 +158,43 @@ class PolicyServiceTest {
         final var policyRuleId = Policy.PolicyRuleId.newBuilder().setUuid(uuid).build();
 
         client
-                .getPolicy(policyRuleId)
+                .getPolicyService(policyRuleId)
                 .subscribe()
                 .with(
-                        policyRuleState -> {
+                        policyRuleService -> {
                             LOGGER.infof(
                                     "Getting policy with ID: %s",
-                                    policyRuleState.getPolicyRuleId().getUuid().getUuid());
-                            message.complete(policyRuleState.getPolicyRuleId().getUuid().getUuid());
+                                    policyRuleService.getPolicyRuleBasic().getPolicyRuleId().getUuid());
+                            message.complete(
+                                    policyRuleService.getPolicyRuleBasic().getPolicyRuleId().getUuid().getUuid());
                         });
+
         assertThat(message.get(5, TimeUnit.SECONDS)).isEqualTo(policyRuleId.getUuid().getUuid());
     }
 
     @Test
-    void shouldGetPolicyByDeviceId()
-            throws ExecutionException, InterruptedException, TimeoutException {
-
+    void shouldGetPolicyDevice() throws ExecutionException, InterruptedException, TimeoutException {
         CompletableFuture<String> message = new CompletableFuture<>();
 
         final var uuid =
                 ContextOuterClass.Uuid.newBuilder()
                         .setUuid(UUID.fromString("0f14d0ab-9608-7862-a9e4-5ed26688389b").toString())
                         .build();
-        final var deviceId = ContextOuterClass.DeviceId.newBuilder().setDeviceUuid(uuid).build();
+        final var policyRuleId = Policy.PolicyRuleId.newBuilder().setUuid(uuid).build();
 
         client
-                .getPolicyByDeviceId(deviceId)
+                .getPolicyDevice(policyRuleId)
                 .subscribe()
                 .with(
-                        policyRuleList -> {
-                            LOGGER.infof("Getting policyRuleList with ID: %s", policyRuleList);
-                            message.complete(policyRuleList.toString());
+                        policyRuleService -> {
+                            LOGGER.infof(
+                                    "Getting policy with ID: %s",
+                                    policyRuleService.getPolicyRuleBasic().getPolicyRuleId().getUuid());
+                            message.complete(
+                                    policyRuleService.getPolicyRuleBasic().getPolicyRuleId().getUuid().getUuid());
                         });
 
-        assertThat(message.get(5, TimeUnit.SECONDS)).isEmpty();
+        assertThat(message.get(5, TimeUnit.SECONDS)).isEqualTo(policyRuleId.getUuid().getUuid());
     }
 
     @Test
diff --git a/src/policy/target/generated-sources/grpc/policy/MutinyPolicyServiceGrpc.java b/src/policy/target/generated-sources/grpc/policy/MutinyPolicyServiceGrpc.java
index bad12a99d..b9d840730 100644
--- a/src/policy/target/generated-sources/grpc/policy/MutinyPolicyServiceGrpc.java
+++ b/src/policy/target/generated-sources/grpc/policy/MutinyPolicyServiceGrpc.java
@@ -36,32 +36,42 @@ public final class MutinyPolicyServiceGrpc implements io.quarkus.grpc.runtime.Mu
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAdd(policy.Policy.PolicyRule request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::policyAdd);
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddService(policy.Policy.PolicyRuleService request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::policyAddService);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdate(policy.Policy.PolicyRule request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::policyUpdate);
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddDevice(policy.Policy.PolicyRuleDevice request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::policyAddDevice);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRule request) {
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateService(policy.Policy.PolicyRuleService request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::policyUpdateService);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateDevice(policy.Policy.PolicyRuleDevice request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::policyUpdateDevice);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRuleId request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::policyDelete);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRule> getPolicy(policy.Policy.PolicyRuleId request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getPolicy);
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleService> getPolicyService(policy.Policy.PolicyRuleId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getPolicyService);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByDeviceId(context.ContextOuterClass.DeviceId request) {
-            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getPolicyByDeviceId);
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleDevice> getPolicyDevice(policy.Policy.PolicyRuleId request) {
+            return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getPolicyDevice);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleServiceList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
             return io.quarkus.grpc.runtime.ClientCalls.oneToOne(request, delegateStub::getPolicyByServiceId);
         }
 
@@ -83,89 +93,115 @@ public final class MutinyPolicyServiceGrpc implements io.quarkus.grpc.runtime.Mu
 
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAdd(policy.Policy.PolicyRule request) {
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddService(policy.Policy.PolicyRuleService request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddDevice(policy.Policy.PolicyRuleDevice request) {
+            throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+        }
+
+        
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateService(policy.Policy.PolicyRuleService request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdate(policy.Policy.PolicyRule request) {
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateDevice(policy.Policy.PolicyRuleDevice request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRule request) {
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRuleId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRule> getPolicy(policy.Policy.PolicyRuleId request) {
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleService> getPolicyService(policy.Policy.PolicyRuleId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByDeviceId(context.ContextOuterClass.DeviceId request) {
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleDevice> getPolicyDevice(policy.Policy.PolicyRuleId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         
-        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
+        public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleServiceList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
             throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
         }
 
         @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
             return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
                     .addMethod(
-                            policy.PolicyServiceGrpc.getPolicyAddMethod(),
+                            policy.PolicyServiceGrpc.getPolicyAddServiceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            policy.Policy.PolicyRuleService,
+                                            policy.Policy.PolicyRuleState>(
+                                            this, METHODID_POLICY_ADD_SERVICE, compression)))
+                    .addMethod(
+                            policy.PolicyServiceGrpc.getPolicyAddDeviceMethod(),
+                            asyncUnaryCall(
+                                    new MethodHandlers<
+                                            policy.Policy.PolicyRuleDevice,
+                                            policy.Policy.PolicyRuleState>(
+                                            this, METHODID_POLICY_ADD_DEVICE, compression)))
+                    .addMethod(
+                            policy.PolicyServiceGrpc.getPolicyUpdateServiceMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            policy.Policy.PolicyRule,
+                                            policy.Policy.PolicyRuleService,
                                             policy.Policy.PolicyRuleState>(
-                                            this, METHODID_POLICY_ADD, compression)))
+                                            this, METHODID_POLICY_UPDATE_SERVICE, compression)))
                     .addMethod(
-                            policy.PolicyServiceGrpc.getPolicyUpdateMethod(),
+                            policy.PolicyServiceGrpc.getPolicyUpdateDeviceMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            policy.Policy.PolicyRule,
+                                            policy.Policy.PolicyRuleDevice,
                                             policy.Policy.PolicyRuleState>(
-                                            this, METHODID_POLICY_UPDATE, compression)))
+                                            this, METHODID_POLICY_UPDATE_DEVICE, compression)))
                     .addMethod(
                             policy.PolicyServiceGrpc.getPolicyDeleteMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            policy.Policy.PolicyRule,
+                                            policy.Policy.PolicyRuleId,
                                             policy.Policy.PolicyRuleState>(
                                             this, METHODID_POLICY_DELETE, compression)))
                     .addMethod(
-                            policy.PolicyServiceGrpc.getGetPolicyMethod(),
+                            policy.PolicyServiceGrpc.getGetPolicyServiceMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
                                             policy.Policy.PolicyRuleId,
-                                            policy.Policy.PolicyRule>(
-                                            this, METHODID_GET_POLICY, compression)))
+                                            policy.Policy.PolicyRuleService>(
+                                            this, METHODID_GET_POLICY_SERVICE, compression)))
                     .addMethod(
-                            policy.PolicyServiceGrpc.getGetPolicyByDeviceIdMethod(),
+                            policy.PolicyServiceGrpc.getGetPolicyDeviceMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
-                                            context.ContextOuterClass.DeviceId,
-                                            policy.Policy.PolicyRuleList>(
-                                            this, METHODID_GET_POLICY_BY_DEVICE_ID, compression)))
+                                            policy.Policy.PolicyRuleId,
+                                            policy.Policy.PolicyRuleDevice>(
+                                            this, METHODID_GET_POLICY_DEVICE, compression)))
                     .addMethod(
                             policy.PolicyServiceGrpc.getGetPolicyByServiceIdMethod(),
                             asyncUnaryCall(
                                     new MethodHandlers<
                                             context.ContextOuterClass.ServiceId,
-                                            policy.Policy.PolicyRuleList>(
+                                            policy.Policy.PolicyRuleServiceList>(
                                             this, METHODID_GET_POLICY_BY_SERVICE_ID, compression)))
                     .build();
         }
     }
 
-    private static final int METHODID_POLICY_ADD = 0;
-    private static final int METHODID_POLICY_UPDATE = 1;
-    private static final int METHODID_POLICY_DELETE = 2;
-    private static final int METHODID_GET_POLICY = 3;
-    private static final int METHODID_GET_POLICY_BY_DEVICE_ID = 4;
-    private static final int METHODID_GET_POLICY_BY_SERVICE_ID = 5;
+    private static final int METHODID_POLICY_ADD_SERVICE = 0;
+    private static final int METHODID_POLICY_ADD_DEVICE = 1;
+    private static final int METHODID_POLICY_UPDATE_SERVICE = 2;
+    private static final int METHODID_POLICY_UPDATE_DEVICE = 3;
+    private static final int METHODID_POLICY_DELETE = 4;
+    private static final int METHODID_GET_POLICY_SERVICE = 5;
+    private static final int METHODID_GET_POLICY_DEVICE = 6;
+    private static final int METHODID_GET_POLICY_BY_SERVICE_ID = 7;
 
     private static final class MethodHandlers<Req, Resp> implements
             io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -186,39 +222,51 @@ public final class MutinyPolicyServiceGrpc implements io.quarkus.grpc.runtime.Mu
         @java.lang.SuppressWarnings("unchecked")
         public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
             switch (methodId) {
-                case METHODID_POLICY_ADD:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRule) request,
+                case METHODID_POLICY_ADD_SERVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRuleService) request,
                             (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver,
                             compression,
-                            serviceImpl::policyAdd);
+                            serviceImpl::policyAddService);
                     break;
-                case METHODID_POLICY_UPDATE:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRule) request,
+                case METHODID_POLICY_ADD_DEVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRuleDevice) request,
                             (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver,
                             compression,
-                            serviceImpl::policyUpdate);
+                            serviceImpl::policyAddDevice);
+                    break;
+                case METHODID_POLICY_UPDATE_SERVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRuleService) request,
+                            (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver,
+                            compression,
+                            serviceImpl::policyUpdateService);
+                    break;
+                case METHODID_POLICY_UPDATE_DEVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRuleDevice) request,
+                            (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver,
+                            compression,
+                            serviceImpl::policyUpdateDevice);
                     break;
                 case METHODID_POLICY_DELETE:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRule) request,
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRuleId) request,
                             (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver,
                             compression,
                             serviceImpl::policyDelete);
                     break;
-                case METHODID_GET_POLICY:
+                case METHODID_GET_POLICY_SERVICE:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRuleId) request,
-                            (io.grpc.stub.StreamObserver<policy.Policy.PolicyRule>) responseObserver,
+                            (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleService>) responseObserver,
                             compression,
-                            serviceImpl::getPolicy);
+                            serviceImpl::getPolicyService);
                     break;
-                case METHODID_GET_POLICY_BY_DEVICE_ID:
-                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.DeviceId) request,
-                            (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleList>) responseObserver,
+                case METHODID_GET_POLICY_DEVICE:
+                    io.quarkus.grpc.runtime.ServerCalls.oneToOne((policy.Policy.PolicyRuleId) request,
+                            (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleDevice>) responseObserver,
                             compression,
-                            serviceImpl::getPolicyByDeviceId);
+                            serviceImpl::getPolicyDevice);
                     break;
                 case METHODID_GET_POLICY_BY_SERVICE_ID:
                     io.quarkus.grpc.runtime.ServerCalls.oneToOne((context.ContextOuterClass.ServiceId) request,
-                            (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleList>) responseObserver,
+                            (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleServiceList>) responseObserver,
                             compression,
                             serviceImpl::getPolicyByServiceId);
                     break;
diff --git a/src/policy/target/generated-sources/grpc/policy/Policy.java b/src/policy/target/generated-sources/grpc/policy/Policy.java
index 787344739..324f67cdd 100644
--- a/src/policy/target/generated-sources/grpc/policy/Policy.java
+++ b/src/policy/target/generated-sources/grpc/policy/Policy.java
@@ -21,180 +21,183 @@ public final class Policy {
       implements com.google.protobuf.ProtocolMessageEnum {
     /**
      * <pre>
-     * Rule is currently inactive
+     * Undefined rule state
      * </pre>
      *
-     * <code>POLICY_INACTIVE = 0;</code>
+     * <code>POLICY_UNDEFINED = 0;</code>
      */
-    POLICY_INACTIVE(0),
+    POLICY_UNDEFINED(0),
     /**
      * <pre>
-     * Rule installation planned
+     * Rule failed
      * </pre>
      *
-     * <code>POLICY_PLANNED = 1;</code>
+     * <code>POLICY_FAILED = 1;</code>
      */
-    POLICY_PLANNED(1),
+    POLICY_FAILED(1),
     /**
      * <pre>
-     * Rule is currently active
+     * Rule is just inserted
      * </pre>
      *
-     * <code>POLICY_ACTIVE = 2;</code>
+     * <code>POLICY_INSERTED = 2;</code>
      */
-    POLICY_ACTIVE(2),
-    UNRECOGNIZED(-1),
-    ;
-
+    POLICY_INSERTED(2),
     /**
      * <pre>
-     * Rule is currently inactive
+     * Rule content is correct
      * </pre>
      *
-     * <code>POLICY_INACTIVE = 0;</code>
+     * <code>POLICY_VALIDATED = 3;</code>
      */
-    public static final int POLICY_INACTIVE_VALUE = 0;
+    POLICY_VALIDATED(3),
     /**
      * <pre>
-     * Rule installation planned
+     * Rule subscribed to Monitoring
      * </pre>
      *
-     * <code>POLICY_PLANNED = 1;</code>
+     * <code>POLICY_PROVISIONED = 4;</code>
      */
-    public static final int POLICY_PLANNED_VALUE = 1;
+    POLICY_PROVISIONED(4),
     /**
      * <pre>
-     * Rule is currently active
+     * Rule is currently active (alarm is just thrown by Monitoring)
      * </pre>
      *
-     * <code>POLICY_ACTIVE = 2;</code>
+     * <code>POLICY_ACTIVE = 5;</code>
      */
-    public static final int POLICY_ACTIVE_VALUE = 2;
-
-
-    public final int getNumber() {
-      if (this == UNRECOGNIZED) {
-        throw new java.lang.IllegalArgumentException(
-            "Can't get the number of an unknown enum value.");
-      }
-      return value;
-    }
-
+    POLICY_ACTIVE(5),
     /**
-     * @param value The numeric wire value of the corresponding enum entry.
-     * @return The enum associated with the given numeric wire value.
-     * @deprecated Use {@link #forNumber(int)} instead.
+     * <pre>
+     * Rule action is successfully enforced
+     * </pre>
+     *
+     * <code>POLICY_ENFORCED = 6;</code>
      */
-    @java.lang.Deprecated
-    public static RuleState valueOf(int value) {
-      return forNumber(value);
-    }
-
+    POLICY_ENFORCED(6),
     /**
-     * @param value The numeric wire value of the corresponding enum entry.
-     * @return The enum associated with the given numeric wire value.
+     * <pre>
+     * The applied rule action did not work as expected
+     * </pre>
+     *
+     * <code>POLICY_INEFFECTIVE = 7;</code>
      */
-    public static RuleState forNumber(int value) {
-      switch (value) {
-        case 0: return POLICY_INACTIVE;
-        case 1: return POLICY_PLANNED;
-        case 2: return POLICY_ACTIVE;
-        default: return null;
-      }
-    }
-
-    public static com.google.protobuf.Internal.EnumLiteMap<RuleState>
-        internalGetValueMap() {
-      return internalValueMap;
-    }
-    private static final com.google.protobuf.Internal.EnumLiteMap<
-        RuleState> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<RuleState>() {
-            public RuleState findValueByNumber(int number) {
-              return RuleState.forNumber(number);
-            }
-          };
-
-    public final com.google.protobuf.Descriptors.EnumValueDescriptor
-        getValueDescriptor() {
-      if (this == UNRECOGNIZED) {
-        throw new java.lang.IllegalStateException(
-            "Can't get the descriptor of an unrecognized enum value.");
-      }
-      return getDescriptor().getValues().get(ordinal());
-    }
-    public final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptorForType() {
-      return getDescriptor();
-    }
-    public static final com.google.protobuf.Descriptors.EnumDescriptor
-        getDescriptor() {
-      return policy.Policy.getDescriptor().getEnumTypes().get(0);
-    }
-
-    private static final RuleState[] VALUES = values();
-
-    public static RuleState valueOf(
-        com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
-      if (desc.getType() != getDescriptor()) {
-        throw new java.lang.IllegalArgumentException(
-          "EnumValueDescriptor is not for this type.");
-      }
-      if (desc.getIndex() == -1) {
-        return UNRECOGNIZED;
-      }
-      return VALUES[desc.getIndex()];
-    }
-
-    private final int value;
-
-    private RuleState(int value) {
-      this.value = value;
-    }
-
-    // @@protoc_insertion_point(enum_scope:policy.RuleState)
-  }
-
-  /**
-   * Protobuf enum {@code policy.PolicyRuleType}
-   */
-  public enum PolicyRuleType
-      implements com.google.protobuf.ProtocolMessageEnum {
+    POLICY_INEFFECTIVE(7),
+    /**
+     * <pre>
+     * The applied rule action did work as expected
+     * </pre>
+     *
+     * <code>POLICY_EFFECTIVE = 8;</code>
+     */
+    POLICY_EFFECTIVE(8),
     /**
      * <pre>
-     * Device-level
+     * Operator requires a policy to change
      * </pre>
      *
-     * <code>POLICYTYPE_DEVICE = 0;</code>
+     * <code>POLICY_UPDATED = 9;</code>
      */
-    POLICYTYPE_DEVICE(0),
+    POLICY_UPDATED(9),
     /**
      * <pre>
-     * Network-wide
+     * Operator requires to remove a policy
      * </pre>
      *
-     * <code>POLICYTYPE_NETWORK = 1;</code>
+     * <code>POLICY_REMOVED = 10;</code>
      */
-    POLICYTYPE_NETWORK(1),
+    POLICY_REMOVED(10),
     UNRECOGNIZED(-1),
     ;
 
     /**
      * <pre>
-     * Device-level
+     * Undefined rule state
+     * </pre>
+     *
+     * <code>POLICY_UNDEFINED = 0;</code>
+     */
+    public static final int POLICY_UNDEFINED_VALUE = 0;
+    /**
+     * <pre>
+     * Rule failed
+     * </pre>
+     *
+     * <code>POLICY_FAILED = 1;</code>
+     */
+    public static final int POLICY_FAILED_VALUE = 1;
+    /**
+     * <pre>
+     * Rule is just inserted
+     * </pre>
+     *
+     * <code>POLICY_INSERTED = 2;</code>
+     */
+    public static final int POLICY_INSERTED_VALUE = 2;
+    /**
+     * <pre>
+     * Rule content is correct
+     * </pre>
+     *
+     * <code>POLICY_VALIDATED = 3;</code>
+     */
+    public static final int POLICY_VALIDATED_VALUE = 3;
+    /**
+     * <pre>
+     * Rule subscribed to Monitoring
+     * </pre>
+     *
+     * <code>POLICY_PROVISIONED = 4;</code>
+     */
+    public static final int POLICY_PROVISIONED_VALUE = 4;
+    /**
+     * <pre>
+     * Rule is currently active (alarm is just thrown by Monitoring)
+     * </pre>
+     *
+     * <code>POLICY_ACTIVE = 5;</code>
+     */
+    public static final int POLICY_ACTIVE_VALUE = 5;
+    /**
+     * <pre>
+     * Rule action is successfully enforced
+     * </pre>
+     *
+     * <code>POLICY_ENFORCED = 6;</code>
+     */
+    public static final int POLICY_ENFORCED_VALUE = 6;
+    /**
+     * <pre>
+     * The applied rule action did not work as expected
+     * </pre>
+     *
+     * <code>POLICY_INEFFECTIVE = 7;</code>
+     */
+    public static final int POLICY_INEFFECTIVE_VALUE = 7;
+    /**
+     * <pre>
+     * The applied rule action did work as expected
+     * </pre>
+     *
+     * <code>POLICY_EFFECTIVE = 8;</code>
+     */
+    public static final int POLICY_EFFECTIVE_VALUE = 8;
+    /**
+     * <pre>
+     * Operator requires a policy to change
      * </pre>
      *
-     * <code>POLICYTYPE_DEVICE = 0;</code>
+     * <code>POLICY_UPDATED = 9;</code>
      */
-    public static final int POLICYTYPE_DEVICE_VALUE = 0;
+    public static final int POLICY_UPDATED_VALUE = 9;
     /**
      * <pre>
-     * Network-wide
+     * Operator requires to remove a policy
      * </pre>
      *
-     * <code>POLICYTYPE_NETWORK = 1;</code>
+     * <code>POLICY_REMOVED = 10;</code>
      */
-    public static final int POLICYTYPE_NETWORK_VALUE = 1;
+    public static final int POLICY_REMOVED_VALUE = 10;
 
 
     public final int getNumber() {
@@ -211,7 +214,7 @@ public final class Policy {
      * @deprecated Use {@link #forNumber(int)} instead.
      */
     @java.lang.Deprecated
-    public static PolicyRuleType valueOf(int value) {
+    public static RuleState valueOf(int value) {
       return forNumber(value);
     }
 
@@ -219,23 +222,32 @@ public final class Policy {
      * @param value The numeric wire value of the corresponding enum entry.
      * @return The enum associated with the given numeric wire value.
      */
-    public static PolicyRuleType forNumber(int value) {
+    public static RuleState forNumber(int value) {
       switch (value) {
-        case 0: return POLICYTYPE_DEVICE;
-        case 1: return POLICYTYPE_NETWORK;
+        case 0: return POLICY_UNDEFINED;
+        case 1: return POLICY_FAILED;
+        case 2: return POLICY_INSERTED;
+        case 3: return POLICY_VALIDATED;
+        case 4: return POLICY_PROVISIONED;
+        case 5: return POLICY_ACTIVE;
+        case 6: return POLICY_ENFORCED;
+        case 7: return POLICY_INEFFECTIVE;
+        case 8: return POLICY_EFFECTIVE;
+        case 9: return POLICY_UPDATED;
+        case 10: return POLICY_REMOVED;
         default: return null;
       }
     }
 
-    public static com.google.protobuf.Internal.EnumLiteMap<PolicyRuleType>
+    public static com.google.protobuf.Internal.EnumLiteMap<RuleState>
         internalGetValueMap() {
       return internalValueMap;
     }
     private static final com.google.protobuf.Internal.EnumLiteMap<
-        PolicyRuleType> internalValueMap =
-          new com.google.protobuf.Internal.EnumLiteMap<PolicyRuleType>() {
-            public PolicyRuleType findValueByNumber(int number) {
-              return PolicyRuleType.forNumber(number);
+        RuleState> internalValueMap =
+          new com.google.protobuf.Internal.EnumLiteMap<RuleState>() {
+            public RuleState findValueByNumber(int number) {
+              return RuleState.forNumber(number);
             }
           };
 
@@ -253,12 +265,12 @@ public final class Policy {
     }
     public static final com.google.protobuf.Descriptors.EnumDescriptor
         getDescriptor() {
-      return policy.Policy.getDescriptor().getEnumTypes().get(1);
+      return policy.Policy.getDescriptor().getEnumTypes().get(0);
     }
 
-    private static final PolicyRuleType[] VALUES = values();
+    private static final RuleState[] VALUES = values();
 
-    public static PolicyRuleType valueOf(
+    public static RuleState valueOf(
         com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
       if (desc.getType() != getDescriptor()) {
         throw new java.lang.IllegalArgumentException(
@@ -272,11 +284,11 @@ public final class Policy {
 
     private final int value;
 
-    private PolicyRuleType(int value) {
+    private RuleState(int value) {
       this.value = value;
     }
 
-    // @@protoc_insertion_point(enum_scope:policy.PolicyRuleType)
+    // @@protoc_insertion_point(enum_scope:policy.RuleState)
   }
 
   public interface PolicyRuleIdOrBuilder extends
@@ -905,27 +917,12 @@ public final class Policy {
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Uuid policyRuleId = 1;</code>
-     * @return Whether the policyRuleId field is set.
-     */
-    boolean hasPolicyRuleId();
-    /**
-     * <code>.context.Uuid policyRuleId = 1;</code>
-     * @return The policyRuleId.
-     */
-    context.ContextOuterClass.Uuid getPolicyRuleId();
-    /**
-     * <code>.context.Uuid policyRuleId = 1;</code>
-     */
-    context.ContextOuterClass.UuidOrBuilder getPolicyRuleIdOrBuilder();
-
-    /**
-     * <code>.policy.RuleState policyRuleState = 2;</code>
+     * <code>.policy.RuleState policyRuleState = 1;</code>
      * @return The enum numeric value on the wire for policyRuleState.
      */
     int getPolicyRuleStateValue();
     /**
-     * <code>.policy.RuleState policyRuleState = 2;</code>
+     * <code>.policy.RuleState policyRuleState = 1;</code>
      * @return The policyRuleState.
      */
     policy.Policy.RuleState getPolicyRuleState();
@@ -976,20 +973,7 @@ public final class Policy {
             case 0:
               done = true;
               break;
-            case 10: {
-              context.ContextOuterClass.Uuid.Builder subBuilder = null;
-              if (policyRuleId_ != null) {
-                subBuilder = policyRuleId_.toBuilder();
-              }
-              policyRuleId_ = input.readMessage(context.ContextOuterClass.Uuid.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(policyRuleId_);
-                policyRuleId_ = subBuilder.buildPartial();
-              }
-
-              break;
-            }
-            case 16: {
+            case 8: {
               int rawValue = input.readEnum();
 
               policyRuleState_ = rawValue;
@@ -1027,43 +1011,17 @@ public final class Policy {
               policy.Policy.PolicyRuleState.class, policy.Policy.PolicyRuleState.Builder.class);
     }
 
-    public static final int POLICYRULEID_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Uuid policyRuleId_;
-    /**
-     * <code>.context.Uuid policyRuleId = 1;</code>
-     * @return Whether the policyRuleId field is set.
-     */
-    @java.lang.Override
-    public boolean hasPolicyRuleId() {
-      return policyRuleId_ != null;
-    }
-    /**
-     * <code>.context.Uuid policyRuleId = 1;</code>
-     * @return The policyRuleId.
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.Uuid getPolicyRuleId() {
-      return policyRuleId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : policyRuleId_;
-    }
-    /**
-     * <code>.context.Uuid policyRuleId = 1;</code>
-     */
-    @java.lang.Override
-    public context.ContextOuterClass.UuidOrBuilder getPolicyRuleIdOrBuilder() {
-      return getPolicyRuleId();
-    }
-
-    public static final int POLICYRULESTATE_FIELD_NUMBER = 2;
+    public static final int POLICYRULESTATE_FIELD_NUMBER = 1;
     private int policyRuleState_;
     /**
-     * <code>.policy.RuleState policyRuleState = 2;</code>
+     * <code>.policy.RuleState policyRuleState = 1;</code>
      * @return The enum numeric value on the wire for policyRuleState.
      */
     @java.lang.Override public int getPolicyRuleStateValue() {
       return policyRuleState_;
     }
     /**
-     * <code>.policy.RuleState policyRuleState = 2;</code>
+     * <code>.policy.RuleState policyRuleState = 1;</code>
      * @return The policyRuleState.
      */
     @java.lang.Override public policy.Policy.RuleState getPolicyRuleState() {
@@ -1086,11 +1044,8 @@ public final class Policy {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (policyRuleId_ != null) {
-        output.writeMessage(1, getPolicyRuleId());
-      }
-      if (policyRuleState_ != policy.Policy.RuleState.POLICY_INACTIVE.getNumber()) {
-        output.writeEnum(2, policyRuleState_);
+      if (policyRuleState_ != policy.Policy.RuleState.POLICY_UNDEFINED.getNumber()) {
+        output.writeEnum(1, policyRuleState_);
       }
       unknownFields.writeTo(output);
     }
@@ -1101,13 +1056,9 @@ public final class Policy {
       if (size != -1) return size;
 
       size = 0;
-      if (policyRuleId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getPolicyRuleId());
-      }
-      if (policyRuleState_ != policy.Policy.RuleState.POLICY_INACTIVE.getNumber()) {
+      if (policyRuleState_ != policy.Policy.RuleState.POLICY_UNDEFINED.getNumber()) {
         size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(2, policyRuleState_);
+          .computeEnumSize(1, policyRuleState_);
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -1124,11 +1075,6 @@ public final class Policy {
       }
       policy.Policy.PolicyRuleState other = (policy.Policy.PolicyRuleState) obj;
 
-      if (hasPolicyRuleId() != other.hasPolicyRuleId()) return false;
-      if (hasPolicyRuleId()) {
-        if (!getPolicyRuleId()
-            .equals(other.getPolicyRuleId())) return false;
-      }
       if (policyRuleState_ != other.policyRuleState_) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
@@ -1141,10 +1087,6 @@ public final class Policy {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasPolicyRuleId()) {
-        hash = (37 * hash) + POLICYRULEID_FIELD_NUMBER;
-        hash = (53 * hash) + getPolicyRuleId().hashCode();
-      }
       hash = (37 * hash) + POLICYRULESTATE_FIELD_NUMBER;
       hash = (53 * hash) + policyRuleState_;
       hash = (29 * hash) + unknownFields.hashCode();
@@ -1280,12 +1222,6 @@ public final class Policy {
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (policyRuleIdBuilder_ == null) {
-          policyRuleId_ = null;
-        } else {
-          policyRuleId_ = null;
-          policyRuleIdBuilder_ = null;
-        }
         policyRuleState_ = 0;
 
         return this;
@@ -1314,11 +1250,6 @@ public final class Policy {
       @java.lang.Override
       public policy.Policy.PolicyRuleState buildPartial() {
         policy.Policy.PolicyRuleState result = new policy.Policy.PolicyRuleState(this);
-        if (policyRuleIdBuilder_ == null) {
-          result.policyRuleId_ = policyRuleId_;
-        } else {
-          result.policyRuleId_ = policyRuleIdBuilder_.build();
-        }
         result.policyRuleState_ = policyRuleState_;
         onBuilt();
         return result;
@@ -1368,9 +1299,6 @@ public final class Policy {
 
       public Builder mergeFrom(policy.Policy.PolicyRuleState other) {
         if (other == policy.Policy.PolicyRuleState.getDefaultInstance()) return this;
-        if (other.hasPolicyRuleId()) {
-          mergePolicyRuleId(other.getPolicyRuleId());
-        }
         if (other.policyRuleState_ != 0) {
           setPolicyRuleStateValue(other.getPolicyRuleStateValue());
         }
@@ -1403,146 +1331,27 @@ public final class Policy {
         return this;
       }
 
-      private context.ContextOuterClass.Uuid policyRuleId_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> policyRuleIdBuilder_;
-      /**
-       * <code>.context.Uuid policyRuleId = 1;</code>
-       * @return Whether the policyRuleId field is set.
-       */
-      public boolean hasPolicyRuleId() {
-        return policyRuleIdBuilder_ != null || policyRuleId_ != null;
-      }
+      private int policyRuleState_ = 0;
       /**
-       * <code>.context.Uuid policyRuleId = 1;</code>
-       * @return The policyRuleId.
+       * <code>.policy.RuleState policyRuleState = 1;</code>
+       * @return The enum numeric value on the wire for policyRuleState.
        */
-      public context.ContextOuterClass.Uuid getPolicyRuleId() {
-        if (policyRuleIdBuilder_ == null) {
-          return policyRuleId_ == null ? context.ContextOuterClass.Uuid.getDefaultInstance() : policyRuleId_;
-        } else {
-          return policyRuleIdBuilder_.getMessage();
-        }
+      @java.lang.Override public int getPolicyRuleStateValue() {
+        return policyRuleState_;
       }
       /**
-       * <code>.context.Uuid policyRuleId = 1;</code>
+       * <code>.policy.RuleState policyRuleState = 1;</code>
+       * @param value The enum numeric value on the wire for policyRuleState to set.
+       * @return This builder for chaining.
        */
-      public Builder setPolicyRuleId(context.ContextOuterClass.Uuid value) {
-        if (policyRuleIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          policyRuleId_ = value;
-          onChanged();
-        } else {
-          policyRuleIdBuilder_.setMessage(value);
-        }
-
+      public Builder setPolicyRuleStateValue(int value) {
+        
+        policyRuleState_ = value;
+        onChanged();
         return this;
       }
       /**
-       * <code>.context.Uuid policyRuleId = 1;</code>
-       */
-      public Builder setPolicyRuleId(
-          context.ContextOuterClass.Uuid.Builder builderForValue) {
-        if (policyRuleIdBuilder_ == null) {
-          policyRuleId_ = builderForValue.build();
-          onChanged();
-        } else {
-          policyRuleIdBuilder_.setMessage(builderForValue.build());
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.Uuid policyRuleId = 1;</code>
-       */
-      public Builder mergePolicyRuleId(context.ContextOuterClass.Uuid value) {
-        if (policyRuleIdBuilder_ == null) {
-          if (policyRuleId_ != null) {
-            policyRuleId_ =
-              context.ContextOuterClass.Uuid.newBuilder(policyRuleId_).mergeFrom(value).buildPartial();
-          } else {
-            policyRuleId_ = value;
-          }
-          onChanged();
-        } else {
-          policyRuleIdBuilder_.mergeFrom(value);
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.Uuid policyRuleId = 1;</code>
-       */
-      public Builder clearPolicyRuleId() {
-        if (policyRuleIdBuilder_ == null) {
-          policyRuleId_ = null;
-          onChanged();
-        } else {
-          policyRuleId_ = null;
-          policyRuleIdBuilder_ = null;
-        }
-
-        return this;
-      }
-      /**
-       * <code>.context.Uuid policyRuleId = 1;</code>
-       */
-      public context.ContextOuterClass.Uuid.Builder getPolicyRuleIdBuilder() {
-        
-        onChanged();
-        return getPolicyRuleIdFieldBuilder().getBuilder();
-      }
-      /**
-       * <code>.context.Uuid policyRuleId = 1;</code>
-       */
-      public context.ContextOuterClass.UuidOrBuilder getPolicyRuleIdOrBuilder() {
-        if (policyRuleIdBuilder_ != null) {
-          return policyRuleIdBuilder_.getMessageOrBuilder();
-        } else {
-          return policyRuleId_ == null ?
-              context.ContextOuterClass.Uuid.getDefaultInstance() : policyRuleId_;
-        }
-      }
-      /**
-       * <code>.context.Uuid policyRuleId = 1;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder> 
-          getPolicyRuleIdFieldBuilder() {
-        if (policyRuleIdBuilder_ == null) {
-          policyRuleIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.Uuid, context.ContextOuterClass.Uuid.Builder, context.ContextOuterClass.UuidOrBuilder>(
-                  getPolicyRuleId(),
-                  getParentForChildren(),
-                  isClean());
-          policyRuleId_ = null;
-        }
-        return policyRuleIdBuilder_;
-      }
-
-      private int policyRuleState_ = 0;
-      /**
-       * <code>.policy.RuleState policyRuleState = 2;</code>
-       * @return The enum numeric value on the wire for policyRuleState.
-       */
-      @java.lang.Override public int getPolicyRuleStateValue() {
-        return policyRuleState_;
-      }
-      /**
-       * <code>.policy.RuleState policyRuleState = 2;</code>
-       * @param value The enum numeric value on the wire for policyRuleState to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPolicyRuleStateValue(int value) {
-        
-        policyRuleState_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>.policy.RuleState policyRuleState = 2;</code>
+       * <code>.policy.RuleState policyRuleState = 1;</code>
        * @return The policyRuleState.
        */
       @java.lang.Override
@@ -1552,7 +1361,7 @@ public final class Policy {
         return result == null ? policy.Policy.RuleState.UNRECOGNIZED : result;
       }
       /**
-       * <code>.policy.RuleState policyRuleState = 2;</code>
+       * <code>.policy.RuleState policyRuleState = 1;</code>
        * @param value The policyRuleState to set.
        * @return This builder for chaining.
        */
@@ -1566,7 +1375,7 @@ public final class Policy {
         return this;
       }
       /**
-       * <code>.policy.RuleState policyRuleState = 2;</code>
+       * <code>.policy.RuleState policyRuleState = 1;</code>
        * @return This builder for chaining.
        */
       public Builder clearPolicyRuleState() {
@@ -1628,51 +1437,180 @@ public final class Policy {
 
   }
 
-  public interface PolicyRuleEventOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleEvent)
+  public interface PolicyRuleBasicOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleBasic)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>.context.Event event = 1;</code>
-     * @return Whether the event field is set.
+     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+     * @return Whether the policyRuleId field is set.
+     */
+    boolean hasPolicyRuleId();
+    /**
+     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+     * @return The policyRuleId.
+     */
+    policy.Policy.PolicyRuleId getPolicyRuleId();
+    /**
+     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+     */
+    policy.Policy.PolicyRuleIdOrBuilder getPolicyRuleIdOrBuilder();
+
+    /**
+     * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+     * @return Whether the policyRuleState field is set.
+     */
+    boolean hasPolicyRuleState();
+    /**
+     * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+     * @return The policyRuleState.
+     */
+    policy.Policy.PolicyRuleState getPolicyRuleState();
+    /**
+     * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+     */
+    policy.Policy.PolicyRuleStateOrBuilder getPolicyRuleStateOrBuilder();
+
+    /**
+     * <code>uint32 priority = 3;</code>
+     * @return The priority.
+     */
+    int getPriority();
+
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    java.util.List<policy.PolicyCondition.PolicyRuleCondition> 
+        getConditionListList();
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    policy.PolicyCondition.PolicyRuleCondition getConditionList(int index);
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    int getConditionListCount();
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    java.util.List<? extends policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
+        getConditionListOrBuilderList();
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    policy.PolicyCondition.PolicyRuleConditionOrBuilder getConditionListOrBuilder(
+        int index);
+
+    /**
+     * <pre>
+     * Evaluation operator to be used
+     * </pre>
+     *
+     * <code>.policy.BooleanOperator booleanOperator = 5;</code>
+     * @return The enum numeric value on the wire for booleanOperator.
+     */
+    int getBooleanOperatorValue();
+    /**
+     * <pre>
+     * Evaluation operator to be used
+     * </pre>
+     *
+     * <code>.policy.BooleanOperator booleanOperator = 5;</code>
+     * @return The booleanOperator.
+     */
+    policy.PolicyCondition.BooleanOperator getBooleanOperator();
+
+    /**
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+     */
+    java.util.List<policy.PolicyAction.PolicyRuleAction> 
+        getActionListList();
+    /**
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+     */
+    policy.PolicyAction.PolicyRuleAction getActionList(int index);
+    /**
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
      */
-    boolean hasEvent();
+    int getActionListCount();
     /**
-     * <code>.context.Event event = 1;</code>
-     * @return The event.
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
      */
-    context.ContextOuterClass.Event getEvent();
+    java.util.List<? extends policy.PolicyAction.PolicyRuleActionOrBuilder> 
+        getActionListOrBuilderList();
     /**
-     * <code>.context.Event event = 1;</code>
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
      */
-    context.ContextOuterClass.EventOrBuilder getEventOrBuilder();
+    policy.PolicyAction.PolicyRuleActionOrBuilder getActionListOrBuilder(
+        int index);
   }
   /**
    * <pre>
-   * IETF draft: Framework for Use of ECA (Event Condition Action) in Network Self Management
-   *     Source: https://datatracker.ietf.org/doc/draft-bwd-netmod-eca-framework/
-   * Event
+   * Basic policy rule attributes
    * </pre>
    *
-   * Protobuf type {@code policy.PolicyRuleEvent}
+   * Protobuf type {@code policy.PolicyRuleBasic}
    */
-  public static final class PolicyRuleEvent extends
+  public static final class PolicyRuleBasic extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:policy.PolicyRuleEvent)
-      PolicyRuleEventOrBuilder {
+      // @@protoc_insertion_point(message_implements:policy.PolicyRuleBasic)
+      PolicyRuleBasicOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use PolicyRuleEvent.newBuilder() to construct.
-    private PolicyRuleEvent(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use PolicyRuleBasic.newBuilder() to construct.
+    private PolicyRuleBasic(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private PolicyRuleEvent() {
+    private PolicyRuleBasic() {
+      conditionList_ = java.util.Collections.emptyList();
+      booleanOperator_ = 0;
+      actionList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new PolicyRuleEvent();
+      return new PolicyRuleBasic();
     }
 
     @java.lang.Override
@@ -1680,7 +1618,7 @@ public final class Policy {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private PolicyRuleEvent(
+    private PolicyRuleBasic(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -1688,6 +1626,7 @@ public final class Policy {
       if (extensionRegistry == null) {
         throw new java.lang.NullPointerException();
       }
+      int mutable_bitField0_ = 0;
       com.google.protobuf.UnknownFieldSet.Builder unknownFields =
           com.google.protobuf.UnknownFieldSet.newBuilder();
       try {
@@ -1699,16 +1638,58 @@ public final class Policy {
               done = true;
               break;
             case 10: {
-              context.ContextOuterClass.Event.Builder subBuilder = null;
-              if (event_ != null) {
-                subBuilder = event_.toBuilder();
+              policy.Policy.PolicyRuleId.Builder subBuilder = null;
+              if (policyRuleId_ != null) {
+                subBuilder = policyRuleId_.toBuilder();
+              }
+              policyRuleId_ = input.readMessage(policy.Policy.PolicyRuleId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(policyRuleId_);
+                policyRuleId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              policy.Policy.PolicyRuleState.Builder subBuilder = null;
+              if (((bitField0_ & 0x00000001) != 0)) {
+                subBuilder = policyRuleState_.toBuilder();
               }
-              event_ = input.readMessage(context.ContextOuterClass.Event.parser(), extensionRegistry);
+              policyRuleState_ = input.readMessage(policy.Policy.PolicyRuleState.parser(), extensionRegistry);
               if (subBuilder != null) {
-                subBuilder.mergeFrom(event_);
-                event_ = subBuilder.buildPartial();
+                subBuilder.mergeFrom(policyRuleState_);
+                policyRuleState_ = subBuilder.buildPartial();
+              }
+              bitField0_ |= 0x00000001;
+              break;
+            }
+            case 24: {
+
+              priority_ = input.readUInt32();
+              break;
+            }
+            case 34: {
+              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
+                conditionList_ = new java.util.ArrayList<policy.PolicyCondition.PolicyRuleCondition>();
+                mutable_bitField0_ |= 0x00000002;
               }
+              conditionList_.add(
+                  input.readMessage(policy.PolicyCondition.PolicyRuleCondition.parser(), extensionRegistry));
+              break;
+            }
+            case 40: {
+              int rawValue = input.readEnum();
 
+              booleanOperator_ = rawValue;
+              break;
+            }
+            case 50: {
+              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
+                actionList_ = new java.util.ArrayList<policy.PolicyAction.PolicyRuleAction>();
+                mutable_bitField0_ |= 0x00000004;
+              }
+              actionList_.add(
+                  input.readMessage(policy.PolicyAction.PolicyRuleAction.parser(), extensionRegistry));
               break;
             }
             default: {
@@ -1726,47 +1707,238 @@ public final class Policy {
         throw new com.google.protobuf.InvalidProtocolBufferException(
             e).setUnfinishedMessage(this);
       } finally {
+        if (((mutable_bitField0_ & 0x00000002) != 0)) {
+          conditionList_ = java.util.Collections.unmodifiableList(conditionList_);
+        }
+        if (((mutable_bitField0_ & 0x00000004) != 0)) {
+          actionList_ = java.util.Collections.unmodifiableList(actionList_);
+        }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
       }
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return policy.Policy.internal_static_policy_PolicyRuleEvent_descriptor;
+      return policy.Policy.internal_static_policy_PolicyRuleBasic_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return policy.Policy.internal_static_policy_PolicyRuleEvent_fieldAccessorTable
+      return policy.Policy.internal_static_policy_PolicyRuleBasic_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              policy.Policy.PolicyRuleEvent.class, policy.Policy.PolicyRuleEvent.Builder.class);
+              policy.Policy.PolicyRuleBasic.class, policy.Policy.PolicyRuleBasic.Builder.class);
     }
 
-    public static final int EVENT_FIELD_NUMBER = 1;
-    private context.ContextOuterClass.Event event_;
+    private int bitField0_;
+    public static final int POLICYRULEID_FIELD_NUMBER = 1;
+    private policy.Policy.PolicyRuleId policyRuleId_;
     /**
-     * <code>.context.Event event = 1;</code>
-     * @return Whether the event field is set.
+     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+     * @return Whether the policyRuleId field is set.
      */
     @java.lang.Override
-    public boolean hasEvent() {
-      return event_ != null;
+    public boolean hasPolicyRuleId() {
+      return policyRuleId_ != null;
     }
     /**
-     * <code>.context.Event event = 1;</code>
-     * @return The event.
+     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+     * @return The policyRuleId.
      */
     @java.lang.Override
-    public context.ContextOuterClass.Event getEvent() {
-      return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
+    public policy.Policy.PolicyRuleId getPolicyRuleId() {
+      return policyRuleId_ == null ? policy.Policy.PolicyRuleId.getDefaultInstance() : policyRuleId_;
+    }
+    /**
+     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+     */
+    @java.lang.Override
+    public policy.Policy.PolicyRuleIdOrBuilder getPolicyRuleIdOrBuilder() {
+      return getPolicyRuleId();
+    }
+
+    public static final int POLICYRULESTATE_FIELD_NUMBER = 2;
+    private policy.Policy.PolicyRuleState policyRuleState_;
+    /**
+     * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+     * @return Whether the policyRuleState field is set.
+     */
+    @java.lang.Override
+    public boolean hasPolicyRuleState() {
+      return ((bitField0_ & 0x00000001) != 0);
+    }
+    /**
+     * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+     * @return The policyRuleState.
+     */
+    @java.lang.Override
+    public policy.Policy.PolicyRuleState getPolicyRuleState() {
+      return policyRuleState_ == null ? policy.Policy.PolicyRuleState.getDefaultInstance() : policyRuleState_;
+    }
+    /**
+     * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+     */
+    @java.lang.Override
+    public policy.Policy.PolicyRuleStateOrBuilder getPolicyRuleStateOrBuilder() {
+      return policyRuleState_ == null ? policy.Policy.PolicyRuleState.getDefaultInstance() : policyRuleState_;
+    }
+
+    public static final int PRIORITY_FIELD_NUMBER = 3;
+    private int priority_;
+    /**
+     * <code>uint32 priority = 3;</code>
+     * @return The priority.
+     */
+    @java.lang.Override
+    public int getPriority() {
+      return priority_;
+    }
+
+    public static final int CONDITIONLIST_FIELD_NUMBER = 4;
+    private java.util.List<policy.PolicyCondition.PolicyRuleCondition> conditionList_;
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<policy.PolicyCondition.PolicyRuleCondition> getConditionListList() {
+      return conditionList_;
+    }
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
+        getConditionListOrBuilderList() {
+      return conditionList_;
+    }
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    @java.lang.Override
+    public int getConditionListCount() {
+      return conditionList_.size();
+    }
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    @java.lang.Override
+    public policy.PolicyCondition.PolicyRuleCondition getConditionList(int index) {
+      return conditionList_.get(index);
+    }
+    /**
+     * <pre>
+     * Event-Condition-Action (ECA) model
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+     */
+    @java.lang.Override
+    public policy.PolicyCondition.PolicyRuleConditionOrBuilder getConditionListOrBuilder(
+        int index) {
+      return conditionList_.get(index);
+    }
+
+    public static final int BOOLEANOPERATOR_FIELD_NUMBER = 5;
+    private int booleanOperator_;
+    /**
+     * <pre>
+     * Evaluation operator to be used
+     * </pre>
+     *
+     * <code>.policy.BooleanOperator booleanOperator = 5;</code>
+     * @return The enum numeric value on the wire for booleanOperator.
+     */
+    @java.lang.Override public int getBooleanOperatorValue() {
+      return booleanOperator_;
+    }
+    /**
+     * <pre>
+     * Evaluation operator to be used
+     * </pre>
+     *
+     * <code>.policy.BooleanOperator booleanOperator = 5;</code>
+     * @return The booleanOperator.
+     */
+    @java.lang.Override public policy.PolicyCondition.BooleanOperator getBooleanOperator() {
+      @SuppressWarnings("deprecation")
+      policy.PolicyCondition.BooleanOperator result = policy.PolicyCondition.BooleanOperator.valueOf(booleanOperator_);
+      return result == null ? policy.PolicyCondition.BooleanOperator.UNRECOGNIZED : result;
+    }
+
+    public static final int ACTIONLIST_FIELD_NUMBER = 6;
+    private java.util.List<policy.PolicyAction.PolicyRuleAction> actionList_;
+    /**
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+     */
+    @java.lang.Override
+    public java.util.List<policy.PolicyAction.PolicyRuleAction> getActionListList() {
+      return actionList_;
+    }
+    /**
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends policy.PolicyAction.PolicyRuleActionOrBuilder> 
+        getActionListOrBuilderList() {
+      return actionList_;
+    }
+    /**
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+     */
+    @java.lang.Override
+    public int getActionListCount() {
+      return actionList_.size();
+    }
+    /**
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+     */
+    @java.lang.Override
+    public policy.PolicyAction.PolicyRuleAction getActionList(int index) {
+      return actionList_.get(index);
     }
     /**
-     * <code>.context.Event event = 1;</code>
+     * <pre>
+     * One or more actions should be applied
+     * </pre>
+     *
+     * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
-      return getEvent();
+    public policy.PolicyAction.PolicyRuleActionOrBuilder getActionListOrBuilder(
+        int index) {
+      return actionList_.get(index);
     }
 
     private byte memoizedIsInitialized = -1;
@@ -1783,8 +1955,23 @@ public final class Policy {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (event_ != null) {
-        output.writeMessage(1, getEvent());
+      if (policyRuleId_ != null) {
+        output.writeMessage(1, getPolicyRuleId());
+      }
+      if (((bitField0_ & 0x00000001) != 0)) {
+        output.writeMessage(2, getPolicyRuleState());
+      }
+      if (priority_ != 0) {
+        output.writeUInt32(3, priority_);
+      }
+      for (int i = 0; i < conditionList_.size(); i++) {
+        output.writeMessage(4, conditionList_.get(i));
+      }
+      if (booleanOperator_ != policy.PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED.getNumber()) {
+        output.writeEnum(5, booleanOperator_);
+      }
+      for (int i = 0; i < actionList_.size(); i++) {
+        output.writeMessage(6, actionList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -1795,9 +1982,29 @@ public final class Policy {
       if (size != -1) return size;
 
       size = 0;
-      if (event_ != null) {
+      if (policyRuleId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getPolicyRuleId());
+      }
+      if (((bitField0_ & 0x00000001) != 0)) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getPolicyRuleState());
+      }
+      if (priority_ != 0) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeUInt32Size(3, priority_);
+      }
+      for (int i = 0; i < conditionList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(4, conditionList_.get(i));
+      }
+      if (booleanOperator_ != policy.PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED.getNumber()) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getEvent());
+          .computeEnumSize(5, booleanOperator_);
+      }
+      for (int i = 0; i < actionList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(6, actionList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -1809,16 +2016,28 @@ public final class Policy {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof policy.Policy.PolicyRuleEvent)) {
+      if (!(obj instanceof policy.Policy.PolicyRuleBasic)) {
         return super.equals(obj);
       }
-      policy.Policy.PolicyRuleEvent other = (policy.Policy.PolicyRuleEvent) obj;
+      policy.Policy.PolicyRuleBasic other = (policy.Policy.PolicyRuleBasic) obj;
 
-      if (hasEvent() != other.hasEvent()) return false;
-      if (hasEvent()) {
-        if (!getEvent()
-            .equals(other.getEvent())) return false;
+      if (hasPolicyRuleId() != other.hasPolicyRuleId()) return false;
+      if (hasPolicyRuleId()) {
+        if (!getPolicyRuleId()
+            .equals(other.getPolicyRuleId())) return false;
+      }
+      if (hasPolicyRuleState() != other.hasPolicyRuleState()) return false;
+      if (hasPolicyRuleState()) {
+        if (!getPolicyRuleState()
+            .equals(other.getPolicyRuleState())) return false;
       }
+      if (getPriority()
+          != other.getPriority()) return false;
+      if (!getConditionListList()
+          .equals(other.getConditionListList())) return false;
+      if (booleanOperator_ != other.booleanOperator_) return false;
+      if (!getActionListList()
+          .equals(other.getActionListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -1830,78 +2049,94 @@ public final class Policy {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasEvent()) {
-        hash = (37 * hash) + EVENT_FIELD_NUMBER;
-        hash = (53 * hash) + getEvent().hashCode();
+      if (hasPolicyRuleId()) {
+        hash = (37 * hash) + POLICYRULEID_FIELD_NUMBER;
+        hash = (53 * hash) + getPolicyRuleId().hashCode();
+      }
+      if (hasPolicyRuleState()) {
+        hash = (37 * hash) + POLICYRULESTATE_FIELD_NUMBER;
+        hash = (53 * hash) + getPolicyRuleState().hashCode();
+      }
+      hash = (37 * hash) + PRIORITY_FIELD_NUMBER;
+      hash = (53 * hash) + getPriority();
+      if (getConditionListCount() > 0) {
+        hash = (37 * hash) + CONDITIONLIST_FIELD_NUMBER;
+        hash = (53 * hash) + getConditionListList().hashCode();
+      }
+      hash = (37 * hash) + BOOLEANOPERATOR_FIELD_NUMBER;
+      hash = (53 * hash) + booleanOperator_;
+      if (getActionListCount() > 0) {
+        hash = (37 * hash) + ACTIONLIST_FIELD_NUMBER;
+        hash = (53 * hash) + getActionListList().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static policy.Policy.PolicyRuleEvent parseFrom(
+    public static policy.Policy.PolicyRuleBasic parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
+    public static policy.Policy.PolicyRuleBasic parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
+    public static policy.Policy.PolicyRuleBasic parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
+    public static policy.Policy.PolicyRuleBasic parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleEvent parseFrom(byte[] data)
+    public static policy.Policy.PolicyRuleBasic parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
+    public static policy.Policy.PolicyRuleBasic parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleEvent parseFrom(java.io.InputStream input)
+    public static policy.Policy.PolicyRuleBasic parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
+    public static policy.Policy.PolicyRuleBasic parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleEvent parseDelimitedFrom(java.io.InputStream input)
+    public static policy.Policy.PolicyRuleBasic parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRuleEvent parseDelimitedFrom(
+    public static policy.Policy.PolicyRuleBasic parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
+    public static policy.Policy.PolicyRuleBasic parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRuleEvent parseFrom(
+    public static policy.Policy.PolicyRuleBasic parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -1914,7 +2149,7 @@ public final class Policy {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(policy.Policy.PolicyRuleEvent prototype) {
+    public static Builder newBuilder(policy.Policy.PolicyRuleBasic prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -1931,31 +2166,29 @@ public final class Policy {
     }
     /**
      * <pre>
-     * IETF draft: Framework for Use of ECA (Event Condition Action) in Network Self Management
-     *     Source: https://datatracker.ietf.org/doc/draft-bwd-netmod-eca-framework/
-     * Event
+     * Basic policy rule attributes
      * </pre>
      *
-     * Protobuf type {@code policy.PolicyRuleEvent}
+     * Protobuf type {@code policy.PolicyRuleBasic}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleEvent)
-        policy.Policy.PolicyRuleEventOrBuilder {
+        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleBasic)
+        policy.Policy.PolicyRuleBasicOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return policy.Policy.internal_static_policy_PolicyRuleEvent_descriptor;
+        return policy.Policy.internal_static_policy_PolicyRuleBasic_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return policy.Policy.internal_static_policy_PolicyRuleEvent_fieldAccessorTable
+        return policy.Policy.internal_static_policy_PolicyRuleBasic_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                policy.Policy.PolicyRuleEvent.class, policy.Policy.PolicyRuleEvent.Builder.class);
+                policy.Policy.PolicyRuleBasic.class, policy.Policy.PolicyRuleBasic.Builder.class);
       }
 
-      // Construct using policy.Policy.PolicyRuleEvent.newBuilder()
+      // Construct using policy.Policy.PolicyRuleBasic.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -1968,16 +2201,41 @@ public final class Policy {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
+          getPolicyRuleStateFieldBuilder();
+          getConditionListFieldBuilder();
+          getActionListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (eventBuilder_ == null) {
-          event_ = null;
+        if (policyRuleIdBuilder_ == null) {
+          policyRuleId_ = null;
+        } else {
+          policyRuleId_ = null;
+          policyRuleIdBuilder_ = null;
+        }
+        if (policyRuleStateBuilder_ == null) {
+          policyRuleState_ = null;
         } else {
-          event_ = null;
-          eventBuilder_ = null;
+          policyRuleStateBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        priority_ = 0;
+
+        if (conditionListBuilder_ == null) {
+          conditionList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+        } else {
+          conditionListBuilder_.clear();
+        }
+        booleanOperator_ = 0;
+
+        if (actionListBuilder_ == null) {
+          actionList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000004);
+        } else {
+          actionListBuilder_.clear();
         }
         return this;
       }
@@ -1985,17 +2243,17 @@ public final class Policy {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return policy.Policy.internal_static_policy_PolicyRuleEvent_descriptor;
+        return policy.Policy.internal_static_policy_PolicyRuleBasic_descriptor;
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRuleEvent getDefaultInstanceForType() {
-        return policy.Policy.PolicyRuleEvent.getDefaultInstance();
+      public policy.Policy.PolicyRuleBasic getDefaultInstanceForType() {
+        return policy.Policy.PolicyRuleBasic.getDefaultInstance();
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRuleEvent build() {
-        policy.Policy.PolicyRuleEvent result = buildPartial();
+      public policy.Policy.PolicyRuleBasic build() {
+        policy.Policy.PolicyRuleBasic result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -2003,25 +2261,56 @@ public final class Policy {
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRuleEvent buildPartial() {
-        policy.Policy.PolicyRuleEvent result = new policy.Policy.PolicyRuleEvent(this);
-        if (eventBuilder_ == null) {
-          result.event_ = event_;
+      public policy.Policy.PolicyRuleBasic buildPartial() {
+        policy.Policy.PolicyRuleBasic result = new policy.Policy.PolicyRuleBasic(this);
+        int from_bitField0_ = bitField0_;
+        int to_bitField0_ = 0;
+        if (policyRuleIdBuilder_ == null) {
+          result.policyRuleId_ = policyRuleId_;
         } else {
-          result.event_ = eventBuilder_.build();
+          result.policyRuleId_ = policyRuleIdBuilder_.build();
         }
-        onBuilt();
-        return result;
-      }
-
-      @java.lang.Override
-      public Builder clone() {
-        return super.clone();
-      }
-      @java.lang.Override
-      public Builder setField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
+        if (((from_bitField0_ & 0x00000001) != 0)) {
+          if (policyRuleStateBuilder_ == null) {
+            result.policyRuleState_ = policyRuleState_;
+          } else {
+            result.policyRuleState_ = policyRuleStateBuilder_.build();
+          }
+          to_bitField0_ |= 0x00000001;
+        }
+        result.priority_ = priority_;
+        if (conditionListBuilder_ == null) {
+          if (((bitField0_ & 0x00000002) != 0)) {
+            conditionList_ = java.util.Collections.unmodifiableList(conditionList_);
+            bitField0_ = (bitField0_ & ~0x00000002);
+          }
+          result.conditionList_ = conditionList_;
+        } else {
+          result.conditionList_ = conditionListBuilder_.build();
+        }
+        result.booleanOperator_ = booleanOperator_;
+        if (actionListBuilder_ == null) {
+          if (((bitField0_ & 0x00000004) != 0)) {
+            actionList_ = java.util.Collections.unmodifiableList(actionList_);
+            bitField0_ = (bitField0_ & ~0x00000004);
+          }
+          result.actionList_ = actionList_;
+        } else {
+          result.actionList_ = actionListBuilder_.build();
+        }
+        result.bitField0_ = to_bitField0_;
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
         return super.setField(field, value);
       }
       @java.lang.Override
@@ -2048,18 +2337,79 @@ public final class Policy {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof policy.Policy.PolicyRuleEvent) {
-          return mergeFrom((policy.Policy.PolicyRuleEvent)other);
+        if (other instanceof policy.Policy.PolicyRuleBasic) {
+          return mergeFrom((policy.Policy.PolicyRuleBasic)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(policy.Policy.PolicyRuleEvent other) {
-        if (other == policy.Policy.PolicyRuleEvent.getDefaultInstance()) return this;
-        if (other.hasEvent()) {
-          mergeEvent(other.getEvent());
+      public Builder mergeFrom(policy.Policy.PolicyRuleBasic other) {
+        if (other == policy.Policy.PolicyRuleBasic.getDefaultInstance()) return this;
+        if (other.hasPolicyRuleId()) {
+          mergePolicyRuleId(other.getPolicyRuleId());
+        }
+        if (other.hasPolicyRuleState()) {
+          mergePolicyRuleState(other.getPolicyRuleState());
+        }
+        if (other.getPriority() != 0) {
+          setPriority(other.getPriority());
+        }
+        if (conditionListBuilder_ == null) {
+          if (!other.conditionList_.isEmpty()) {
+            if (conditionList_.isEmpty()) {
+              conditionList_ = other.conditionList_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+            } else {
+              ensureConditionListIsMutable();
+              conditionList_.addAll(other.conditionList_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.conditionList_.isEmpty()) {
+            if (conditionListBuilder_.isEmpty()) {
+              conditionListBuilder_.dispose();
+              conditionListBuilder_ = null;
+              conditionList_ = other.conditionList_;
+              bitField0_ = (bitField0_ & ~0x00000002);
+              conditionListBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getConditionListFieldBuilder() : null;
+            } else {
+              conditionListBuilder_.addAllMessages(other.conditionList_);
+            }
+          }
+        }
+        if (other.booleanOperator_ != 0) {
+          setBooleanOperatorValue(other.getBooleanOperatorValue());
+        }
+        if (actionListBuilder_ == null) {
+          if (!other.actionList_.isEmpty()) {
+            if (actionList_.isEmpty()) {
+              actionList_ = other.actionList_;
+              bitField0_ = (bitField0_ & ~0x00000004);
+            } else {
+              ensureActionListIsMutable();
+              actionList_.addAll(other.actionList_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.actionList_.isEmpty()) {
+            if (actionListBuilder_.isEmpty()) {
+              actionListBuilder_.dispose();
+              actionListBuilder_ = null;
+              actionList_ = other.actionList_;
+              bitField0_ = (bitField0_ & ~0x00000004);
+              actionListBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getActionListFieldBuilder() : null;
+            } else {
+              actionListBuilder_.addAllMessages(other.actionList_);
+            }
+          }
         }
         this.mergeUnknownFields(other.unknownFields);
         onChanged();
@@ -2076,11 +2426,11 @@ public final class Policy {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        policy.Policy.PolicyRuleEvent parsedMessage = null;
+        policy.Policy.PolicyRuleBasic parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (policy.Policy.PolicyRuleEvent) e.getUnfinishedMessage();
+          parsedMessage = (policy.Policy.PolicyRuleBasic) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -2089,895 +2439,2707 @@ public final class Policy {
         }
         return this;
       }
+      private int bitField0_;
 
-      private context.ContextOuterClass.Event event_;
+      private policy.Policy.PolicyRuleId policyRuleId_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> eventBuilder_;
+          policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleId.Builder, policy.Policy.PolicyRuleIdOrBuilder> policyRuleIdBuilder_;
       /**
-       * <code>.context.Event event = 1;</code>
-       * @return Whether the event field is set.
+       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+       * @return Whether the policyRuleId field is set.
        */
-      public boolean hasEvent() {
-        return eventBuilder_ != null || event_ != null;
+      public boolean hasPolicyRuleId() {
+        return policyRuleIdBuilder_ != null || policyRuleId_ != null;
       }
       /**
-       * <code>.context.Event event = 1;</code>
-       * @return The event.
+       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+       * @return The policyRuleId.
        */
-      public context.ContextOuterClass.Event getEvent() {
-        if (eventBuilder_ == null) {
-          return event_ == null ? context.ContextOuterClass.Event.getDefaultInstance() : event_;
+      public policy.Policy.PolicyRuleId getPolicyRuleId() {
+        if (policyRuleIdBuilder_ == null) {
+          return policyRuleId_ == null ? policy.Policy.PolicyRuleId.getDefaultInstance() : policyRuleId_;
         } else {
-          return eventBuilder_.getMessage();
+          return policyRuleIdBuilder_.getMessage();
         }
       }
       /**
-       * <code>.context.Event event = 1;</code>
+       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
        */
-      public Builder setEvent(context.ContextOuterClass.Event value) {
-        if (eventBuilder_ == null) {
+      public Builder setPolicyRuleId(policy.Policy.PolicyRuleId value) {
+        if (policyRuleIdBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          event_ = value;
+          policyRuleId_ = value;
           onChanged();
         } else {
-          eventBuilder_.setMessage(value);
+          policyRuleIdBuilder_.setMessage(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.Event event = 1;</code>
+       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
        */
-      public Builder setEvent(
-          context.ContextOuterClass.Event.Builder builderForValue) {
-        if (eventBuilder_ == null) {
-          event_ = builderForValue.build();
+      public Builder setPolicyRuleId(
+          policy.Policy.PolicyRuleId.Builder builderForValue) {
+        if (policyRuleIdBuilder_ == null) {
+          policyRuleId_ = builderForValue.build();
           onChanged();
         } else {
-          eventBuilder_.setMessage(builderForValue.build());
+          policyRuleIdBuilder_.setMessage(builderForValue.build());
         }
 
         return this;
       }
       /**
-       * <code>.context.Event event = 1;</code>
+       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
        */
-      public Builder mergeEvent(context.ContextOuterClass.Event value) {
-        if (eventBuilder_ == null) {
-          if (event_ != null) {
-            event_ =
-              context.ContextOuterClass.Event.newBuilder(event_).mergeFrom(value).buildPartial();
+      public Builder mergePolicyRuleId(policy.Policy.PolicyRuleId value) {
+        if (policyRuleIdBuilder_ == null) {
+          if (policyRuleId_ != null) {
+            policyRuleId_ =
+              policy.Policy.PolicyRuleId.newBuilder(policyRuleId_).mergeFrom(value).buildPartial();
           } else {
-            event_ = value;
+            policyRuleId_ = value;
           }
           onChanged();
         } else {
-          eventBuilder_.mergeFrom(value);
+          policyRuleIdBuilder_.mergeFrom(value);
         }
 
         return this;
       }
       /**
-       * <code>.context.Event event = 1;</code>
+       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
        */
-      public Builder clearEvent() {
-        if (eventBuilder_ == null) {
-          event_ = null;
+      public Builder clearPolicyRuleId() {
+        if (policyRuleIdBuilder_ == null) {
+          policyRuleId_ = null;
           onChanged();
         } else {
-          event_ = null;
-          eventBuilder_ = null;
+          policyRuleId_ = null;
+          policyRuleIdBuilder_ = null;
         }
 
         return this;
       }
       /**
-       * <code>.context.Event event = 1;</code>
+       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
        */
-      public context.ContextOuterClass.Event.Builder getEventBuilder() {
+      public policy.Policy.PolicyRuleId.Builder getPolicyRuleIdBuilder() {
         
         onChanged();
-        return getEventFieldBuilder().getBuilder();
+        return getPolicyRuleIdFieldBuilder().getBuilder();
       }
       /**
-       * <code>.context.Event event = 1;</code>
+       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
        */
-      public context.ContextOuterClass.EventOrBuilder getEventOrBuilder() {
-        if (eventBuilder_ != null) {
-          return eventBuilder_.getMessageOrBuilder();
+      public policy.Policy.PolicyRuleIdOrBuilder getPolicyRuleIdOrBuilder() {
+        if (policyRuleIdBuilder_ != null) {
+          return policyRuleIdBuilder_.getMessageOrBuilder();
         } else {
-          return event_ == null ?
-              context.ContextOuterClass.Event.getDefaultInstance() : event_;
+          return policyRuleId_ == null ?
+              policy.Policy.PolicyRuleId.getDefaultInstance() : policyRuleId_;
         }
       }
       /**
-       * <code>.context.Event event = 1;</code>
+       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
        */
       private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder> 
-          getEventFieldBuilder() {
-        if (eventBuilder_ == null) {
-          eventBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.Event, context.ContextOuterClass.Event.Builder, context.ContextOuterClass.EventOrBuilder>(
-                  getEvent(),
+          policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleId.Builder, policy.Policy.PolicyRuleIdOrBuilder> 
+          getPolicyRuleIdFieldBuilder() {
+        if (policyRuleIdBuilder_ == null) {
+          policyRuleIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleId.Builder, policy.Policy.PolicyRuleIdOrBuilder>(
+                  getPolicyRuleId(),
                   getParentForChildren(),
                   isClean());
-          event_ = null;
+          policyRuleId_ = null;
         }
-        return eventBuilder_;
+        return policyRuleIdBuilder_;
       }
-      @java.lang.Override
-      public final Builder setUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.setUnknownFields(unknownFields);
+
+      private policy.Policy.PolicyRuleState policyRuleState_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          policy.Policy.PolicyRuleState, policy.Policy.PolicyRuleState.Builder, policy.Policy.PolicyRuleStateOrBuilder> policyRuleStateBuilder_;
+      /**
+       * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+       * @return Whether the policyRuleState field is set.
+       */
+      public boolean hasPolicyRuleState() {
+        return ((bitField0_ & 0x00000001) != 0);
+      }
+      /**
+       * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+       * @return The policyRuleState.
+       */
+      public policy.Policy.PolicyRuleState getPolicyRuleState() {
+        if (policyRuleStateBuilder_ == null) {
+          return policyRuleState_ == null ? policy.Policy.PolicyRuleState.getDefaultInstance() : policyRuleState_;
+        } else {
+          return policyRuleStateBuilder_.getMessage();
+        }
+      }
+      /**
+       * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+       */
+      public Builder setPolicyRuleState(policy.Policy.PolicyRuleState value) {
+        if (policyRuleStateBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          policyRuleState_ = value;
+          onChanged();
+        } else {
+          policyRuleStateBuilder_.setMessage(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+       */
+      public Builder setPolicyRuleState(
+          policy.Policy.PolicyRuleState.Builder builderForValue) {
+        if (policyRuleStateBuilder_ == null) {
+          policyRuleState_ = builderForValue.build();
+          onChanged();
+        } else {
+          policyRuleStateBuilder_.setMessage(builderForValue.build());
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+       */
+      public Builder mergePolicyRuleState(policy.Policy.PolicyRuleState value) {
+        if (policyRuleStateBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0) &&
+              policyRuleState_ != null &&
+              policyRuleState_ != policy.Policy.PolicyRuleState.getDefaultInstance()) {
+            policyRuleState_ =
+              policy.Policy.PolicyRuleState.newBuilder(policyRuleState_).mergeFrom(value).buildPartial();
+          } else {
+            policyRuleState_ = value;
+          }
+          onChanged();
+        } else {
+          policyRuleStateBuilder_.mergeFrom(value);
+        }
+        bitField0_ |= 0x00000001;
+        return this;
+      }
+      /**
+       * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+       */
+      public Builder clearPolicyRuleState() {
+        if (policyRuleStateBuilder_ == null) {
+          policyRuleState_ = null;
+          onChanged();
+        } else {
+          policyRuleStateBuilder_.clear();
+        }
+        bitField0_ = (bitField0_ & ~0x00000001);
+        return this;
+      }
+      /**
+       * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+       */
+      public policy.Policy.PolicyRuleState.Builder getPolicyRuleStateBuilder() {
+        bitField0_ |= 0x00000001;
+        onChanged();
+        return getPolicyRuleStateFieldBuilder().getBuilder();
+      }
+      /**
+       * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+       */
+      public policy.Policy.PolicyRuleStateOrBuilder getPolicyRuleStateOrBuilder() {
+        if (policyRuleStateBuilder_ != null) {
+          return policyRuleStateBuilder_.getMessageOrBuilder();
+        } else {
+          return policyRuleState_ == null ?
+              policy.Policy.PolicyRuleState.getDefaultInstance() : policyRuleState_;
+        }
+      }
+      /**
+       * <code>optional .policy.PolicyRuleState policyRuleState = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          policy.Policy.PolicyRuleState, policy.Policy.PolicyRuleState.Builder, policy.Policy.PolicyRuleStateOrBuilder> 
+          getPolicyRuleStateFieldBuilder() {
+        if (policyRuleStateBuilder_ == null) {
+          policyRuleStateBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              policy.Policy.PolicyRuleState, policy.Policy.PolicyRuleState.Builder, policy.Policy.PolicyRuleStateOrBuilder>(
+                  getPolicyRuleState(),
+                  getParentForChildren(),
+                  isClean());
+          policyRuleState_ = null;
+        }
+        return policyRuleStateBuilder_;
       }
 
+      private int priority_ ;
+      /**
+       * <code>uint32 priority = 3;</code>
+       * @return The priority.
+       */
       @java.lang.Override
-      public final Builder mergeUnknownFields(
-          final com.google.protobuf.UnknownFieldSet unknownFields) {
-        return super.mergeUnknownFields(unknownFields);
+      public int getPriority() {
+        return priority_;
+      }
+      /**
+       * <code>uint32 priority = 3;</code>
+       * @param value The priority to set.
+       * @return This builder for chaining.
+       */
+      public Builder setPriority(int value) {
+        
+        priority_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <code>uint32 priority = 3;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearPriority() {
+        
+        priority_ = 0;
+        onChanged();
+        return this;
       }
 
+      private java.util.List<policy.PolicyCondition.PolicyRuleCondition> conditionList_ =
+        java.util.Collections.emptyList();
+      private void ensureConditionListIsMutable() {
+        if (!((bitField0_ & 0x00000002) != 0)) {
+          conditionList_ = new java.util.ArrayList<policy.PolicyCondition.PolicyRuleCondition>(conditionList_);
+          bitField0_ |= 0x00000002;
+         }
+      }
 
-      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleEvent)
-    }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          policy.PolicyCondition.PolicyRuleCondition, policy.PolicyCondition.PolicyRuleCondition.Builder, policy.PolicyCondition.PolicyRuleConditionOrBuilder> conditionListBuilder_;
+
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public java.util.List<policy.PolicyCondition.PolicyRuleCondition> getConditionListList() {
+        if (conditionListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(conditionList_);
+        } else {
+          return conditionListBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public int getConditionListCount() {
+        if (conditionListBuilder_ == null) {
+          return conditionList_.size();
+        } else {
+          return conditionListBuilder_.getCount();
+        }
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public policy.PolicyCondition.PolicyRuleCondition getConditionList(int index) {
+        if (conditionListBuilder_ == null) {
+          return conditionList_.get(index);
+        } else {
+          return conditionListBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public Builder setConditionList(
+          int index, policy.PolicyCondition.PolicyRuleCondition value) {
+        if (conditionListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureConditionListIsMutable();
+          conditionList_.set(index, value);
+          onChanged();
+        } else {
+          conditionListBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public Builder setConditionList(
+          int index, policy.PolicyCondition.PolicyRuleCondition.Builder builderForValue) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
+          conditionList_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          conditionListBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public Builder addConditionList(policy.PolicyCondition.PolicyRuleCondition value) {
+        if (conditionListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureConditionListIsMutable();
+          conditionList_.add(value);
+          onChanged();
+        } else {
+          conditionListBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public Builder addConditionList(
+          int index, policy.PolicyCondition.PolicyRuleCondition value) {
+        if (conditionListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureConditionListIsMutable();
+          conditionList_.add(index, value);
+          onChanged();
+        } else {
+          conditionListBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public Builder addConditionList(
+          policy.PolicyCondition.PolicyRuleCondition.Builder builderForValue) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
+          conditionList_.add(builderForValue.build());
+          onChanged();
+        } else {
+          conditionListBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public Builder addConditionList(
+          int index, policy.PolicyCondition.PolicyRuleCondition.Builder builderForValue) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
+          conditionList_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          conditionListBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public Builder addAllConditionList(
+          java.lang.Iterable<? extends policy.PolicyCondition.PolicyRuleCondition> values) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, conditionList_);
+          onChanged();
+        } else {
+          conditionListBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public Builder clearConditionList() {
+        if (conditionListBuilder_ == null) {
+          conditionList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000002);
+          onChanged();
+        } else {
+          conditionListBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public Builder removeConditionList(int index) {
+        if (conditionListBuilder_ == null) {
+          ensureConditionListIsMutable();
+          conditionList_.remove(index);
+          onChanged();
+        } else {
+          conditionListBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public policy.PolicyCondition.PolicyRuleCondition.Builder getConditionListBuilder(
+          int index) {
+        return getConditionListFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public policy.PolicyCondition.PolicyRuleConditionOrBuilder getConditionListOrBuilder(
+          int index) {
+        if (conditionListBuilder_ == null) {
+          return conditionList_.get(index);  } else {
+          return conditionListBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public java.util.List<? extends policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
+           getConditionListOrBuilderList() {
+        if (conditionListBuilder_ != null) {
+          return conditionListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(conditionList_);
+        }
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public policy.PolicyCondition.PolicyRuleCondition.Builder addConditionListBuilder() {
+        return getConditionListFieldBuilder().addBuilder(
+            policy.PolicyCondition.PolicyRuleCondition.getDefaultInstance());
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public policy.PolicyCondition.PolicyRuleCondition.Builder addConditionListBuilder(
+          int index) {
+        return getConditionListFieldBuilder().addBuilder(
+            index, policy.PolicyCondition.PolicyRuleCondition.getDefaultInstance());
+      }
+      /**
+       * <pre>
+       * Event-Condition-Action (ECA) model
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleCondition conditionList = 4;</code>
+       */
+      public java.util.List<policy.PolicyCondition.PolicyRuleCondition.Builder> 
+           getConditionListBuilderList() {
+        return getConditionListFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          policy.PolicyCondition.PolicyRuleCondition, policy.PolicyCondition.PolicyRuleCondition.Builder, policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
+          getConditionListFieldBuilder() {
+        if (conditionListBuilder_ == null) {
+          conditionListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              policy.PolicyCondition.PolicyRuleCondition, policy.PolicyCondition.PolicyRuleCondition.Builder, policy.PolicyCondition.PolicyRuleConditionOrBuilder>(
+                  conditionList_,
+                  ((bitField0_ & 0x00000002) != 0),
+                  getParentForChildren(),
+                  isClean());
+          conditionList_ = null;
+        }
+        return conditionListBuilder_;
+      }
+
+      private int booleanOperator_ = 0;
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 5;</code>
+       * @return The enum numeric value on the wire for booleanOperator.
+       */
+      @java.lang.Override public int getBooleanOperatorValue() {
+        return booleanOperator_;
+      }
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 5;</code>
+       * @param value The enum numeric value on the wire for booleanOperator to set.
+       * @return This builder for chaining.
+       */
+      public Builder setBooleanOperatorValue(int value) {
+        
+        booleanOperator_ = value;
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 5;</code>
+       * @return The booleanOperator.
+       */
+      @java.lang.Override
+      public policy.PolicyCondition.BooleanOperator getBooleanOperator() {
+        @SuppressWarnings("deprecation")
+        policy.PolicyCondition.BooleanOperator result = policy.PolicyCondition.BooleanOperator.valueOf(booleanOperator_);
+        return result == null ? policy.PolicyCondition.BooleanOperator.UNRECOGNIZED : result;
+      }
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 5;</code>
+       * @param value The booleanOperator to set.
+       * @return This builder for chaining.
+       */
+      public Builder setBooleanOperator(policy.PolicyCondition.BooleanOperator value) {
+        if (value == null) {
+          throw new NullPointerException();
+        }
+        
+        booleanOperator_ = value.getNumber();
+        onChanged();
+        return this;
+      }
+      /**
+       * <pre>
+       * Evaluation operator to be used
+       * </pre>
+       *
+       * <code>.policy.BooleanOperator booleanOperator = 5;</code>
+       * @return This builder for chaining.
+       */
+      public Builder clearBooleanOperator() {
+        
+        booleanOperator_ = 0;
+        onChanged();
+        return this;
+      }
+
+      private java.util.List<policy.PolicyAction.PolicyRuleAction> actionList_ =
+        java.util.Collections.emptyList();
+      private void ensureActionListIsMutable() {
+        if (!((bitField0_ & 0x00000004) != 0)) {
+          actionList_ = new java.util.ArrayList<policy.PolicyAction.PolicyRuleAction>(actionList_);
+          bitField0_ |= 0x00000004;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          policy.PolicyAction.PolicyRuleAction, policy.PolicyAction.PolicyRuleAction.Builder, policy.PolicyAction.PolicyRuleActionOrBuilder> actionListBuilder_;
+
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public java.util.List<policy.PolicyAction.PolicyRuleAction> getActionListList() {
+        if (actionListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(actionList_);
+        } else {
+          return actionListBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public int getActionListCount() {
+        if (actionListBuilder_ == null) {
+          return actionList_.size();
+        } else {
+          return actionListBuilder_.getCount();
+        }
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public policy.PolicyAction.PolicyRuleAction getActionList(int index) {
+        if (actionListBuilder_ == null) {
+          return actionList_.get(index);
+        } else {
+          return actionListBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public Builder setActionList(
+          int index, policy.PolicyAction.PolicyRuleAction value) {
+        if (actionListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureActionListIsMutable();
+          actionList_.set(index, value);
+          onChanged();
+        } else {
+          actionListBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public Builder setActionList(
+          int index, policy.PolicyAction.PolicyRuleAction.Builder builderForValue) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
+          actionList_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          actionListBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public Builder addActionList(policy.PolicyAction.PolicyRuleAction value) {
+        if (actionListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureActionListIsMutable();
+          actionList_.add(value);
+          onChanged();
+        } else {
+          actionListBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public Builder addActionList(
+          int index, policy.PolicyAction.PolicyRuleAction value) {
+        if (actionListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureActionListIsMutable();
+          actionList_.add(index, value);
+          onChanged();
+        } else {
+          actionListBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public Builder addActionList(
+          policy.PolicyAction.PolicyRuleAction.Builder builderForValue) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
+          actionList_.add(builderForValue.build());
+          onChanged();
+        } else {
+          actionListBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public Builder addActionList(
+          int index, policy.PolicyAction.PolicyRuleAction.Builder builderForValue) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
+          actionList_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          actionListBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public Builder addAllActionList(
+          java.lang.Iterable<? extends policy.PolicyAction.PolicyRuleAction> values) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, actionList_);
+          onChanged();
+        } else {
+          actionListBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public Builder clearActionList() {
+        if (actionListBuilder_ == null) {
+          actionList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000004);
+          onChanged();
+        } else {
+          actionListBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public Builder removeActionList(int index) {
+        if (actionListBuilder_ == null) {
+          ensureActionListIsMutable();
+          actionList_.remove(index);
+          onChanged();
+        } else {
+          actionListBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public policy.PolicyAction.PolicyRuleAction.Builder getActionListBuilder(
+          int index) {
+        return getActionListFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public policy.PolicyAction.PolicyRuleActionOrBuilder getActionListOrBuilder(
+          int index) {
+        if (actionListBuilder_ == null) {
+          return actionList_.get(index);  } else {
+          return actionListBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public java.util.List<? extends policy.PolicyAction.PolicyRuleActionOrBuilder> 
+           getActionListOrBuilderList() {
+        if (actionListBuilder_ != null) {
+          return actionListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(actionList_);
+        }
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public policy.PolicyAction.PolicyRuleAction.Builder addActionListBuilder() {
+        return getActionListFieldBuilder().addBuilder(
+            policy.PolicyAction.PolicyRuleAction.getDefaultInstance());
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public policy.PolicyAction.PolicyRuleAction.Builder addActionListBuilder(
+          int index) {
+        return getActionListFieldBuilder().addBuilder(
+            index, policy.PolicyAction.PolicyRuleAction.getDefaultInstance());
+      }
+      /**
+       * <pre>
+       * One or more actions should be applied
+       * </pre>
+       *
+       * <code>repeated .policy.PolicyRuleAction actionList = 6;</code>
+       */
+      public java.util.List<policy.PolicyAction.PolicyRuleAction.Builder> 
+           getActionListBuilderList() {
+        return getActionListFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          policy.PolicyAction.PolicyRuleAction, policy.PolicyAction.PolicyRuleAction.Builder, policy.PolicyAction.PolicyRuleActionOrBuilder> 
+          getActionListFieldBuilder() {
+        if (actionListBuilder_ == null) {
+          actionListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              policy.PolicyAction.PolicyRuleAction, policy.PolicyAction.PolicyRuleAction.Builder, policy.PolicyAction.PolicyRuleActionOrBuilder>(
+                  actionList_,
+                  ((bitField0_ & 0x00000004) != 0),
+                  getParentForChildren(),
+                  isClean());
+          actionList_ = null;
+        }
+        return actionListBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleBasic)
+    }
+
+    // @@protoc_insertion_point(class_scope:policy.PolicyRuleBasic)
+    private static final policy.Policy.PolicyRuleBasic DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleBasic();
+    }
+
+    public static policy.Policy.PolicyRuleBasic getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<PolicyRuleBasic>
+        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleBasic>() {
+      @java.lang.Override
+      public PolicyRuleBasic parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PolicyRuleBasic(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<PolicyRuleBasic> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PolicyRuleBasic> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public policy.Policy.PolicyRuleBasic getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface PolicyRuleServiceOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleService)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <pre>
+     * Basic policy rule attributes
+     * </pre>
+     *
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     * @return Whether the policyRuleBasic field is set.
+     */
+    boolean hasPolicyRuleBasic();
+    /**
+     * <pre>
+     * Basic policy rule attributes
+     * </pre>
+     *
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     * @return The policyRuleBasic.
+     */
+    policy.Policy.PolicyRuleBasic getPolicyRuleBasic();
+    /**
+     * <pre>
+     * Basic policy rule attributes
+     * </pre>
+     *
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     */
+    policy.Policy.PolicyRuleBasicOrBuilder getPolicyRuleBasicOrBuilder();
+
+    /**
+     * <pre>
+     * Affected service and (some of) its device(s)
+     * </pre>
+     *
+     * <code>.context.ServiceId serviceId = 2;</code>
+     * @return Whether the serviceId field is set.
+     */
+    boolean hasServiceId();
+    /**
+     * <pre>
+     * Affected service and (some of) its device(s)
+     * </pre>
+     *
+     * <code>.context.ServiceId serviceId = 2;</code>
+     * @return The serviceId.
+     */
+    context.ContextOuterClass.ServiceId getServiceId();
+    /**
+     * <pre>
+     * Affected service and (some of) its device(s)
+     * </pre>
+     *
+     * <code>.context.ServiceId serviceId = 2;</code>
+     */
+    context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
+
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    java.util.List<context.ContextOuterClass.DeviceId> 
+        getDeviceListList();
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    context.ContextOuterClass.DeviceId getDeviceList(int index);
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    int getDeviceListCount();
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
+        getDeviceListOrBuilderList();
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
+        int index);
+  }
+  /**
+   * <pre>
+   * Service-oriented policy rule
+   * </pre>
+   *
+   * Protobuf type {@code policy.PolicyRuleService}
+   */
+  public static final class PolicyRuleService extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:policy.PolicyRuleService)
+      PolicyRuleServiceOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use PolicyRuleService.newBuilder() to construct.
+    private PolicyRuleService(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private PolicyRuleService() {
+      deviceList_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new PolicyRuleService();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PolicyRuleService(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              policy.Policy.PolicyRuleBasic.Builder subBuilder = null;
+              if (policyRuleBasic_ != null) {
+                subBuilder = policyRuleBasic_.toBuilder();
+              }
+              policyRuleBasic_ = input.readMessage(policy.Policy.PolicyRuleBasic.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(policyRuleBasic_);
+                policyRuleBasic_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              context.ContextOuterClass.ServiceId.Builder subBuilder = null;
+              if (serviceId_ != null) {
+                subBuilder = serviceId_.toBuilder();
+              }
+              serviceId_ = input.readMessage(context.ContextOuterClass.ServiceId.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(serviceId_);
+                serviceId_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 26: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                deviceList_ = new java.util.ArrayList<context.ContextOuterClass.DeviceId>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              deviceList_.add(
+                  input.readMessage(context.ContextOuterClass.DeviceId.parser(), extensionRegistry));
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          deviceList_ = java.util.Collections.unmodifiableList(deviceList_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return policy.Policy.internal_static_policy_PolicyRuleService_descriptor;
+    }
 
-    // @@protoc_insertion_point(class_scope:policy.PolicyRuleEvent)
-    private static final policy.Policy.PolicyRuleEvent DEFAULT_INSTANCE;
-    static {
-      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleEvent();
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return policy.Policy.internal_static_policy_PolicyRuleService_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              policy.Policy.PolicyRuleService.class, policy.Policy.PolicyRuleService.Builder.class);
+    }
+
+    public static final int POLICYRULEBASIC_FIELD_NUMBER = 1;
+    private policy.Policy.PolicyRuleBasic policyRuleBasic_;
+    /**
+     * <pre>
+     * Basic policy rule attributes
+     * </pre>
+     *
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     * @return Whether the policyRuleBasic field is set.
+     */
+    @java.lang.Override
+    public boolean hasPolicyRuleBasic() {
+      return policyRuleBasic_ != null;
+    }
+    /**
+     * <pre>
+     * Basic policy rule attributes
+     * </pre>
+     *
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     * @return The policyRuleBasic.
+     */
+    @java.lang.Override
+    public policy.Policy.PolicyRuleBasic getPolicyRuleBasic() {
+      return policyRuleBasic_ == null ? policy.Policy.PolicyRuleBasic.getDefaultInstance() : policyRuleBasic_;
+    }
+    /**
+     * <pre>
+     * Basic policy rule attributes
+     * </pre>
+     *
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     */
+    @java.lang.Override
+    public policy.Policy.PolicyRuleBasicOrBuilder getPolicyRuleBasicOrBuilder() {
+      return getPolicyRuleBasic();
+    }
+
+    public static final int SERVICEID_FIELD_NUMBER = 2;
+    private context.ContextOuterClass.ServiceId serviceId_;
+    /**
+     * <pre>
+     * Affected service and (some of) its device(s)
+     * </pre>
+     *
+     * <code>.context.ServiceId serviceId = 2;</code>
+     * @return Whether the serviceId field is set.
+     */
+    @java.lang.Override
+    public boolean hasServiceId() {
+      return serviceId_ != null;
+    }
+    /**
+     * <pre>
+     * Affected service and (some of) its device(s)
+     * </pre>
+     *
+     * <code>.context.ServiceId serviceId = 2;</code>
+     * @return The serviceId.
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ServiceId getServiceId() {
+      return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+    }
+    /**
+     * <pre>
+     * Affected service and (some of) its device(s)
+     * </pre>
+     *
+     * <code>.context.ServiceId serviceId = 2;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
+      return getServiceId();
+    }
+
+    public static final int DEVICELIST_FIELD_NUMBER = 3;
+    private java.util.List<context.ContextOuterClass.DeviceId> deviceList_;
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<context.ContextOuterClass.DeviceId> getDeviceListList() {
+      return deviceList_;
+    }
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
+        getDeviceListOrBuilderList() {
+      return deviceList_;
+    }
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    @java.lang.Override
+    public int getDeviceListCount() {
+      return deviceList_.size();
+    }
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceId getDeviceList(int index) {
+      return deviceList_.get(index);
+    }
+    /**
+     * <pre>
+     * List of devices this service is traversing (not exhaustive)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 3;</code>
+     */
+    @java.lang.Override
+    public context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
+        int index) {
+      return deviceList_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      if (policyRuleBasic_ != null) {
+        output.writeMessage(1, getPolicyRuleBasic());
+      }
+      if (serviceId_ != null) {
+        output.writeMessage(2, getServiceId());
+      }
+      for (int i = 0; i < deviceList_.size(); i++) {
+        output.writeMessage(3, deviceList_.get(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      if (policyRuleBasic_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, getPolicyRuleBasic());
+      }
+      if (serviceId_ != null) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(2, getServiceId());
+      }
+      for (int i = 0; i < deviceList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(3, deviceList_.get(i));
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
+      }
+      if (!(obj instanceof policy.Policy.PolicyRuleService)) {
+        return super.equals(obj);
+      }
+      policy.Policy.PolicyRuleService other = (policy.Policy.PolicyRuleService) obj;
+
+      if (hasPolicyRuleBasic() != other.hasPolicyRuleBasic()) return false;
+      if (hasPolicyRuleBasic()) {
+        if (!getPolicyRuleBasic()
+            .equals(other.getPolicyRuleBasic())) return false;
+      }
+      if (hasServiceId() != other.hasServiceId()) return false;
+      if (hasServiceId()) {
+        if (!getServiceId()
+            .equals(other.getServiceId())) return false;
+      }
+      if (!getDeviceListList()
+          .equals(other.getDeviceListList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
+      }
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (hasPolicyRuleBasic()) {
+        hash = (37 * hash) + POLICYRULEBASIC_FIELD_NUMBER;
+        hash = (53 * hash) + getPolicyRuleBasic().hashCode();
+      }
+      if (hasServiceId()) {
+        hash = (37 * hash) + SERVICEID_FIELD_NUMBER;
+        hash = (53 * hash) + getServiceId().hashCode();
+      }
+      if (getDeviceListCount() > 0) {
+        hash = (37 * hash) + DEVICELIST_FIELD_NUMBER;
+        hash = (53 * hash) + getDeviceListList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static policy.Policy.PolicyRuleService parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.Policy.PolicyRuleService parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleService parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.Policy.PolicyRuleService parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleService parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.Policy.PolicyRuleService parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleService parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.Policy.PolicyRuleService parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
-
-    public static policy.Policy.PolicyRuleEvent getDefaultInstance() {
-      return DEFAULT_INSTANCE;
+    public static policy.Policy.PolicyRuleService parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
     }
-
-    private static final com.google.protobuf.Parser<PolicyRuleEvent>
-        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleEvent>() {
-      @java.lang.Override
-      public PolicyRuleEvent parsePartialFrom(
-          com.google.protobuf.CodedInputStream input,
-          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-          throws com.google.protobuf.InvalidProtocolBufferException {
-        return new PolicyRuleEvent(input, extensionRegistry);
-      }
-    };
-
-    public static com.google.protobuf.Parser<PolicyRuleEvent> parser() {
-      return PARSER;
+    public static policy.Policy.PolicyRuleService parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleService parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.Policy.PolicyRuleService parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<PolicyRuleEvent> getParserForType() {
-      return PARSER;
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(policy.Policy.PolicyRuleService prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
-
     @java.lang.Override
-    public policy.Policy.PolicyRuleEvent getDefaultInstanceForType() {
-      return DEFAULT_INSTANCE;
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
     }
 
-  }
-
-  public interface PolicyRuleOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:policy.PolicyRule)
-      com.google.protobuf.MessageOrBuilder {
-
-    /**
-     * <pre>
-     * Basic policy rule attributes
-     * </pre>
-     *
-     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
-     * @return Whether the policyRuleId field is set.
-     */
-    boolean hasPolicyRuleId();
-    /**
-     * <pre>
-     * Basic policy rule attributes
-     * </pre>
-     *
-     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
-     * @return The policyRuleId.
-     */
-    policy.Policy.PolicyRuleId getPolicyRuleId();
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
     /**
      * <pre>
-     * Basic policy rule attributes
+     * Service-oriented policy rule
      * </pre>
      *
-     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+     * Protobuf type {@code policy.PolicyRuleService}
      */
-    policy.Policy.PolicyRuleIdOrBuilder getPolicyRuleIdOrBuilder();
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleService)
+        policy.Policy.PolicyRuleServiceOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return policy.Policy.internal_static_policy_PolicyRuleService_descriptor;
+      }
 
-    /**
-     * <code>.policy.PolicyRuleType policyRuleType = 2;</code>
-     * @return The enum numeric value on the wire for policyRuleType.
-     */
-    int getPolicyRuleTypeValue();
-    /**
-     * <code>.policy.PolicyRuleType policyRuleType = 2;</code>
-     * @return The policyRuleType.
-     */
-    policy.Policy.PolicyRuleType getPolicyRuleType();
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return policy.Policy.internal_static_policy_PolicyRuleService_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                policy.Policy.PolicyRuleService.class, policy.Policy.PolicyRuleService.Builder.class);
+      }
 
-    /**
-     * <code>uint32 priority = 3;</code>
-     * @return The priority.
-     */
-    int getPriority();
+      // Construct using policy.Policy.PolicyRuleService.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
+      }
 
-    /**
-     * <pre>
-     * Event-Condition-Action model
-     * </pre>
-     *
-     * <code>.policy.PolicyRuleEvent event = 4;</code>
-     * @return Whether the event field is set.
-     */
-    boolean hasEvent();
-    /**
-     * <pre>
-     * Event-Condition-Action model
-     * </pre>
-     *
-     * <code>.policy.PolicyRuleEvent event = 4;</code>
-     * @return The event.
-     */
-    policy.Policy.PolicyRuleEvent getEvent();
-    /**
-     * <pre>
-     * Event-Condition-Action model
-     * </pre>
-     *
-     * <code>.policy.PolicyRuleEvent event = 4;</code>
-     */
-    policy.Policy.PolicyRuleEventOrBuilder getEventOrBuilder();
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
+      }
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getDeviceListFieldBuilder();
+        }
+      }
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (policyRuleBasicBuilder_ == null) {
+          policyRuleBasic_ = null;
+        } else {
+          policyRuleBasic_ = null;
+          policyRuleBasicBuilder_ = null;
+        }
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = null;
+        } else {
+          serviceId_ = null;
+          serviceIdBuilder_ = null;
+        }
+        if (deviceListBuilder_ == null) {
+          deviceList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+        } else {
+          deviceListBuilder_.clear();
+        }
+        return this;
+      }
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return policy.Policy.internal_static_policy_PolicyRuleService_descriptor;
+      }
+
+      @java.lang.Override
+      public policy.Policy.PolicyRuleService getDefaultInstanceForType() {
+        return policy.Policy.PolicyRuleService.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public policy.Policy.PolicyRuleService build() {
+        policy.Policy.PolicyRuleService result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
+      }
+
+      @java.lang.Override
+      public policy.Policy.PolicyRuleService buildPartial() {
+        policy.Policy.PolicyRuleService result = new policy.Policy.PolicyRuleService(this);
+        int from_bitField0_ = bitField0_;
+        if (policyRuleBasicBuilder_ == null) {
+          result.policyRuleBasic_ = policyRuleBasic_;
+        } else {
+          result.policyRuleBasic_ = policyRuleBasicBuilder_.build();
+        }
+        if (serviceIdBuilder_ == null) {
+          result.serviceId_ = serviceId_;
+        } else {
+          result.serviceId_ = serviceIdBuilder_.build();
+        }
+        if (deviceListBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            deviceList_ = java.util.Collections.unmodifiableList(deviceList_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.deviceList_ = deviceList_;
+        } else {
+          result.deviceList_ = deviceListBuilder_.build();
+        }
+        onBuilt();
+        return result;
+      }
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
+      }
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof policy.Policy.PolicyRuleService) {
+          return mergeFrom((policy.Policy.PolicyRuleService)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
+      }
+
+      public Builder mergeFrom(policy.Policy.PolicyRuleService other) {
+        if (other == policy.Policy.PolicyRuleService.getDefaultInstance()) return this;
+        if (other.hasPolicyRuleBasic()) {
+          mergePolicyRuleBasic(other.getPolicyRuleBasic());
+        }
+        if (other.hasServiceId()) {
+          mergeServiceId(other.getServiceId());
+        }
+        if (deviceListBuilder_ == null) {
+          if (!other.deviceList_.isEmpty()) {
+            if (deviceList_.isEmpty()) {
+              deviceList_ = other.deviceList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensureDeviceListIsMutable();
+              deviceList_.addAll(other.deviceList_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.deviceList_.isEmpty()) {
+            if (deviceListBuilder_.isEmpty()) {
+              deviceListBuilder_.dispose();
+              deviceListBuilder_ = null;
+              deviceList_ = other.deviceList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              deviceListBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getDeviceListFieldBuilder() : null;
+            } else {
+              deviceListBuilder_.addAllMessages(other.deviceList_);
+            }
+          }
+        }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
+      }
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
 
-    /**
-     * <pre>
-     * One or more conditions must be met
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-     */
-    java.util.List<policy.PolicyCondition.PolicyRuleCondition> 
-        getConditionListList();
-    /**
-     * <pre>
-     * One or more conditions must be met
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-     */
-    policy.PolicyCondition.PolicyRuleCondition getConditionList(int index);
-    /**
-     * <pre>
-     * One or more conditions must be met
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-     */
-    int getConditionListCount();
-    /**
-     * <pre>
-     * One or more conditions must be met
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-     */
-    java.util.List<? extends policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
-        getConditionListOrBuilderList();
-    /**
-     * <pre>
-     * One or more conditions must be met
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-     */
-    policy.PolicyCondition.PolicyRuleConditionOrBuilder getConditionListOrBuilder(
-        int index);
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        policy.Policy.PolicyRuleService parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (policy.Policy.PolicyRuleService) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
+        return this;
+      }
+      private int bitField0_;
 
-    /**
-     * <pre>
-     * Evaluation operator to be used
-     * </pre>
-     *
-     * <code>.policy.BooleanOperator booleanOperator = 6;</code>
-     * @return The enum numeric value on the wire for booleanOperator.
-     */
-    int getBooleanOperatorValue();
-    /**
-     * <pre>
-     * Evaluation operator to be used
-     * </pre>
-     *
-     * <code>.policy.BooleanOperator booleanOperator = 6;</code>
-     * @return The booleanOperator.
-     */
-    policy.PolicyCondition.BooleanOperator getBooleanOperator();
+      private policy.Policy.PolicyRuleBasic policyRuleBasic_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          policy.Policy.PolicyRuleBasic, policy.Policy.PolicyRuleBasic.Builder, policy.Policy.PolicyRuleBasicOrBuilder> policyRuleBasicBuilder_;
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       * @return Whether the policyRuleBasic field is set.
+       */
+      public boolean hasPolicyRuleBasic() {
+        return policyRuleBasicBuilder_ != null || policyRuleBasic_ != null;
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       * @return The policyRuleBasic.
+       */
+      public policy.Policy.PolicyRuleBasic getPolicyRuleBasic() {
+        if (policyRuleBasicBuilder_ == null) {
+          return policyRuleBasic_ == null ? policy.Policy.PolicyRuleBasic.getDefaultInstance() : policyRuleBasic_;
+        } else {
+          return policyRuleBasicBuilder_.getMessage();
+        }
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public Builder setPolicyRuleBasic(policy.Policy.PolicyRuleBasic value) {
+        if (policyRuleBasicBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          policyRuleBasic_ = value;
+          onChanged();
+        } else {
+          policyRuleBasicBuilder_.setMessage(value);
+        }
 
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
-    java.util.List<policy.PolicyAction.PolicyRuleAction> 
-        getActionListList();
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
-    policy.PolicyAction.PolicyRuleAction getActionList(int index);
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
-    int getActionListCount();
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
-    java.util.List<? extends policy.PolicyAction.PolicyRuleActionOrBuilder> 
-        getActionListOrBuilderList();
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
-    policy.PolicyAction.PolicyRuleActionOrBuilder getActionListOrBuilder(
-        int index);
+        return this;
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public Builder setPolicyRuleBasic(
+          policy.Policy.PolicyRuleBasic.Builder builderForValue) {
+        if (policyRuleBasicBuilder_ == null) {
+          policyRuleBasic_ = builderForValue.build();
+          onChanged();
+        } else {
+          policyRuleBasicBuilder_.setMessage(builderForValue.build());
+        }
 
-    /**
-     * <pre>
-     * Affected service and devices
-     * </pre>
-     *
-     * <code>.context.ServiceId serviceId = 8;</code>
-     * @return Whether the serviceId field is set.
-     */
-    boolean hasServiceId();
-    /**
-     * <pre>
-     * Affected service and devices
-     * </pre>
-     *
-     * <code>.context.ServiceId serviceId = 8;</code>
-     * @return The serviceId.
-     */
-    context.ContextOuterClass.ServiceId getServiceId();
-    /**
-     * <pre>
-     * Affected service and devices
-     * </pre>
-     *
-     * <code>.context.ServiceId serviceId = 8;</code>
-     */
-    context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder();
+        return this;
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public Builder mergePolicyRuleBasic(policy.Policy.PolicyRuleBasic value) {
+        if (policyRuleBasicBuilder_ == null) {
+          if (policyRuleBasic_ != null) {
+            policyRuleBasic_ =
+              policy.Policy.PolicyRuleBasic.newBuilder(policyRuleBasic_).mergeFrom(value).buildPartial();
+          } else {
+            policyRuleBasic_ = value;
+          }
+          onChanged();
+        } else {
+          policyRuleBasicBuilder_.mergeFrom(value);
+        }
 
-    /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
-     */
-    java.util.List<context.ContextOuterClass.DeviceId> 
-        getDeviceListList();
-    /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
-     */
-    context.ContextOuterClass.DeviceId getDeviceList(int index);
-    /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
-     */
-    int getDeviceListCount();
-    /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
-     */
-    java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
-        getDeviceListOrBuilderList();
-    /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
-     */
-    context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
-        int index);
-  }
-  /**
-   * <pre>
-   * Policy rule partially complies with IETF’s:
-   *     RFC 3060: https://datatracker.ietf.org/doc/html/rfc3060
-   *     RFC 3460: https://datatracker.ietf.org/doc/html/rfc3460
-   * Enhanced with a policy rule event according to the ECA model
-   * </pre>
-   *
-   * Protobuf type {@code policy.PolicyRule}
-   */
-  public static final class PolicyRule extends
-      com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:policy.PolicyRule)
-      PolicyRuleOrBuilder {
-  private static final long serialVersionUID = 0L;
-    // Use PolicyRule.newBuilder() to construct.
-    private PolicyRule(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
-      super(builder);
-    }
-    private PolicyRule() {
-      policyRuleType_ = 0;
-      conditionList_ = java.util.Collections.emptyList();
-      booleanOperator_ = 0;
-      actionList_ = java.util.Collections.emptyList();
-      deviceList_ = java.util.Collections.emptyList();
-    }
+        return this;
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public Builder clearPolicyRuleBasic() {
+        if (policyRuleBasicBuilder_ == null) {
+          policyRuleBasic_ = null;
+          onChanged();
+        } else {
+          policyRuleBasic_ = null;
+          policyRuleBasicBuilder_ = null;
+        }
 
-    @java.lang.Override
-    @SuppressWarnings({"unused"})
-    protected java.lang.Object newInstance(
-        UnusedPrivateParameter unused) {
-      return new PolicyRule();
-    }
+        return this;
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public policy.Policy.PolicyRuleBasic.Builder getPolicyRuleBasicBuilder() {
+        
+        onChanged();
+        return getPolicyRuleBasicFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public policy.Policy.PolicyRuleBasicOrBuilder getPolicyRuleBasicOrBuilder() {
+        if (policyRuleBasicBuilder_ != null) {
+          return policyRuleBasicBuilder_.getMessageOrBuilder();
+        } else {
+          return policyRuleBasic_ == null ?
+              policy.Policy.PolicyRuleBasic.getDefaultInstance() : policyRuleBasic_;
+        }
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          policy.Policy.PolicyRuleBasic, policy.Policy.PolicyRuleBasic.Builder, policy.Policy.PolicyRuleBasicOrBuilder> 
+          getPolicyRuleBasicFieldBuilder() {
+        if (policyRuleBasicBuilder_ == null) {
+          policyRuleBasicBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              policy.Policy.PolicyRuleBasic, policy.Policy.PolicyRuleBasic.Builder, policy.Policy.PolicyRuleBasicOrBuilder>(
+                  getPolicyRuleBasic(),
+                  getParentForChildren(),
+                  isClean());
+          policyRuleBasic_ = null;
+        }
+        return policyRuleBasicBuilder_;
+      }
 
-    @java.lang.Override
-    public final com.google.protobuf.UnknownFieldSet
-    getUnknownFields() {
-      return this.unknownFields;
-    }
-    private PolicyRule(
-        com.google.protobuf.CodedInputStream input,
-        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
-        throws com.google.protobuf.InvalidProtocolBufferException {
-      this();
-      if (extensionRegistry == null) {
-        throw new java.lang.NullPointerException();
+      private context.ContextOuterClass.ServiceId serviceId_;
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> serviceIdBuilder_;
+      /**
+       * <pre>
+       * Affected service and (some of) its device(s)
+       * </pre>
+       *
+       * <code>.context.ServiceId serviceId = 2;</code>
+       * @return Whether the serviceId field is set.
+       */
+      public boolean hasServiceId() {
+        return serviceIdBuilder_ != null || serviceId_ != null;
       }
-      int mutable_bitField0_ = 0;
-      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
-          com.google.protobuf.UnknownFieldSet.newBuilder();
-      try {
-        boolean done = false;
-        while (!done) {
-          int tag = input.readTag();
-          switch (tag) {
-            case 0:
-              done = true;
-              break;
-            case 10: {
-              policy.Policy.PolicyRuleId.Builder subBuilder = null;
-              if (policyRuleId_ != null) {
-                subBuilder = policyRuleId_.toBuilder();
-              }
-              policyRuleId_ = input.readMessage(policy.Policy.PolicyRuleId.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(policyRuleId_);
-                policyRuleId_ = subBuilder.buildPartial();
-              }
+      /**
+       * <pre>
+       * Affected service and (some of) its device(s)
+       * </pre>
+       *
+       * <code>.context.ServiceId serviceId = 2;</code>
+       * @return The serviceId.
+       */
+      public context.ContextOuterClass.ServiceId getServiceId() {
+        if (serviceIdBuilder_ == null) {
+          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+        } else {
+          return serviceIdBuilder_.getMessage();
+        }
+      }
+      /**
+       * <pre>
+       * Affected service and (some of) its device(s)
+       * </pre>
+       *
+       * <code>.context.ServiceId serviceId = 2;</code>
+       */
+      public Builder setServiceId(context.ContextOuterClass.ServiceId value) {
+        if (serviceIdBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          serviceId_ = value;
+          onChanged();
+        } else {
+          serviceIdBuilder_.setMessage(value);
+        }
 
-              break;
-            }
-            case 16: {
-              int rawValue = input.readEnum();
+        return this;
+      }
+      /**
+       * <pre>
+       * Affected service and (some of) its device(s)
+       * </pre>
+       *
+       * <code>.context.ServiceId serviceId = 2;</code>
+       */
+      public Builder setServiceId(
+          context.ContextOuterClass.ServiceId.Builder builderForValue) {
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = builderForValue.build();
+          onChanged();
+        } else {
+          serviceIdBuilder_.setMessage(builderForValue.build());
+        }
 
-              policyRuleType_ = rawValue;
-              break;
-            }
-            case 24: {
+        return this;
+      }
+      /**
+       * <pre>
+       * Affected service and (some of) its device(s)
+       * </pre>
+       *
+       * <code>.context.ServiceId serviceId = 2;</code>
+       */
+      public Builder mergeServiceId(context.ContextOuterClass.ServiceId value) {
+        if (serviceIdBuilder_ == null) {
+          if (serviceId_ != null) {
+            serviceId_ =
+              context.ContextOuterClass.ServiceId.newBuilder(serviceId_).mergeFrom(value).buildPartial();
+          } else {
+            serviceId_ = value;
+          }
+          onChanged();
+        } else {
+          serviceIdBuilder_.mergeFrom(value);
+        }
 
-              priority_ = input.readUInt32();
-              break;
-            }
-            case 34: {
-              policy.Policy.PolicyRuleEvent.Builder subBuilder = null;
-              if (event_ != null) {
-                subBuilder = event_.toBuilder();
-              }
-              event_ = input.readMessage(policy.Policy.PolicyRuleEvent.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(event_);
-                event_ = subBuilder.buildPartial();
-              }
+        return this;
+      }
+      /**
+       * <pre>
+       * Affected service and (some of) its device(s)
+       * </pre>
+       *
+       * <code>.context.ServiceId serviceId = 2;</code>
+       */
+      public Builder clearServiceId() {
+        if (serviceIdBuilder_ == null) {
+          serviceId_ = null;
+          onChanged();
+        } else {
+          serviceId_ = null;
+          serviceIdBuilder_ = null;
+        }
 
-              break;
-            }
-            case 42: {
-              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                conditionList_ = new java.util.ArrayList<policy.PolicyCondition.PolicyRuleCondition>();
-                mutable_bitField0_ |= 0x00000001;
-              }
-              conditionList_.add(
-                  input.readMessage(policy.PolicyCondition.PolicyRuleCondition.parser(), extensionRegistry));
-              break;
-            }
-            case 48: {
-              int rawValue = input.readEnum();
+        return this;
+      }
+      /**
+       * <pre>
+       * Affected service and (some of) its device(s)
+       * </pre>
+       *
+       * <code>.context.ServiceId serviceId = 2;</code>
+       */
+      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
+        
+        onChanged();
+        return getServiceIdFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       * Affected service and (some of) its device(s)
+       * </pre>
+       *
+       * <code>.context.ServiceId serviceId = 2;</code>
+       */
+      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
+        if (serviceIdBuilder_ != null) {
+          return serviceIdBuilder_.getMessageOrBuilder();
+        } else {
+          return serviceId_ == null ?
+              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+        }
+      }
+      /**
+       * <pre>
+       * Affected service and (some of) its device(s)
+       * </pre>
+       *
+       * <code>.context.ServiceId serviceId = 2;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> 
+          getServiceIdFieldBuilder() {
+        if (serviceIdBuilder_ == null) {
+          serviceIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder>(
+                  getServiceId(),
+                  getParentForChildren(),
+                  isClean());
+          serviceId_ = null;
+        }
+        return serviceIdBuilder_;
+      }
 
-              booleanOperator_ = rawValue;
-              break;
-            }
-            case 58: {
-              if (!((mutable_bitField0_ & 0x00000002) != 0)) {
-                actionList_ = new java.util.ArrayList<policy.PolicyAction.PolicyRuleAction>();
-                mutable_bitField0_ |= 0x00000002;
-              }
-              actionList_.add(
-                  input.readMessage(policy.PolicyAction.PolicyRuleAction.parser(), extensionRegistry));
-              break;
-            }
-            case 66: {
-              context.ContextOuterClass.ServiceId.Builder subBuilder = null;
-              if (serviceId_ != null) {
-                subBuilder = serviceId_.toBuilder();
-              }
-              serviceId_ = input.readMessage(context.ContextOuterClass.ServiceId.parser(), extensionRegistry);
-              if (subBuilder != null) {
-                subBuilder.mergeFrom(serviceId_);
-                serviceId_ = subBuilder.buildPartial();
-              }
+      private java.util.List<context.ContextOuterClass.DeviceId> deviceList_ =
+        java.util.Collections.emptyList();
+      private void ensureDeviceListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          deviceList_ = new java.util.ArrayList<context.ContextOuterClass.DeviceId>(deviceList_);
+          bitField0_ |= 0x00000001;
+         }
+      }
 
-              break;
-            }
-            case 74: {
-              if (!((mutable_bitField0_ & 0x00000004) != 0)) {
-                deviceList_ = new java.util.ArrayList<context.ContextOuterClass.DeviceId>();
-                mutable_bitField0_ |= 0x00000004;
-              }
-              deviceList_.add(
-                  input.readMessage(context.ContextOuterClass.DeviceId.parser(), extensionRegistry));
-              break;
-            }
-            default: {
-              if (!parseUnknownField(
-                  input, unknownFields, extensionRegistry, tag)) {
-                done = true;
-              }
-              break;
-            }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder> deviceListBuilder_;
+
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public java.util.List<context.ContextOuterClass.DeviceId> getDeviceListList() {
+        if (deviceListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(deviceList_);
+        } else {
+          return deviceListBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public int getDeviceListCount() {
+        if (deviceListBuilder_ == null) {
+          return deviceList_.size();
+        } else {
+          return deviceListBuilder_.getCount();
+        }
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceId getDeviceList(int index) {
+        if (deviceListBuilder_ == null) {
+          return deviceList_.get(index);
+        } else {
+          return deviceListBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public Builder setDeviceList(
+          int index, context.ContextOuterClass.DeviceId value) {
+        if (deviceListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
           }
+          ensureDeviceListIsMutable();
+          deviceList_.set(index, value);
+          onChanged();
+        } else {
+          deviceListBuilder_.setMessage(index, value);
         }
-      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-        throw e.setUnfinishedMessage(this);
-      } catch (java.io.IOException e) {
-        throw new com.google.protobuf.InvalidProtocolBufferException(
-            e).setUnfinishedMessage(this);
-      } finally {
-        if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          conditionList_ = java.util.Collections.unmodifiableList(conditionList_);
+        return this;
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public Builder setDeviceList(
+          int index, context.ContextOuterClass.DeviceId.Builder builderForValue) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          deviceList_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          deviceListBuilder_.setMessage(index, builderForValue.build());
         }
-        if (((mutable_bitField0_ & 0x00000002) != 0)) {
-          actionList_ = java.util.Collections.unmodifiableList(actionList_);
+        return this;
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public Builder addDeviceList(context.ContextOuterClass.DeviceId value) {
+        if (deviceListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureDeviceListIsMutable();
+          deviceList_.add(value);
+          onChanged();
+        } else {
+          deviceListBuilder_.addMessage(value);
         }
-        if (((mutable_bitField0_ & 0x00000004) != 0)) {
-          deviceList_ = java.util.Collections.unmodifiableList(deviceList_);
+        return this;
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public Builder addDeviceList(
+          int index, context.ContextOuterClass.DeviceId value) {
+        if (deviceListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureDeviceListIsMutable();
+          deviceList_.add(index, value);
+          onChanged();
+        } else {
+          deviceListBuilder_.addMessage(index, value);
         }
-        this.unknownFields = unknownFields.build();
-        makeExtensionsImmutable();
+        return this;
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public Builder addDeviceList(
+          context.ContextOuterClass.DeviceId.Builder builderForValue) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          deviceList_.add(builderForValue.build());
+          onChanged();
+        } else {
+          deviceListBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public Builder addDeviceList(
+          int index, context.ContextOuterClass.DeviceId.Builder builderForValue) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          deviceList_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          deviceListBuilder_.addMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public Builder addAllDeviceList(
+          java.lang.Iterable<? extends context.ContextOuterClass.DeviceId> values) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, deviceList_);
+          onChanged();
+        } else {
+          deviceListBuilder_.addAllMessages(values);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public Builder clearDeviceList() {
+        if (deviceListBuilder_ == null) {
+          deviceList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
+          onChanged();
+        } else {
+          deviceListBuilder_.clear();
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public Builder removeDeviceList(int index) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          deviceList_.remove(index);
+          onChanged();
+        } else {
+          deviceListBuilder_.remove(index);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceId.Builder getDeviceListBuilder(
+          int index) {
+        return getDeviceListFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
+          int index) {
+        if (deviceListBuilder_ == null) {
+          return deviceList_.get(index);  } else {
+          return deviceListBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
+           getDeviceListOrBuilderList() {
+        if (deviceListBuilder_ != null) {
+          return deviceListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(deviceList_);
+        }
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceId.Builder addDeviceListBuilder() {
+        return getDeviceListFieldBuilder().addBuilder(
+            context.ContextOuterClass.DeviceId.getDefaultInstance());
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public context.ContextOuterClass.DeviceId.Builder addDeviceListBuilder(
+          int index) {
+        return getDeviceListFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.DeviceId.getDefaultInstance());
+      }
+      /**
+       * <pre>
+       * List of devices this service is traversing (not exhaustive)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 3;</code>
+       */
+      public java.util.List<context.ContextOuterClass.DeviceId.Builder> 
+           getDeviceListBuilderList() {
+        return getDeviceListFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder> 
+          getDeviceListFieldBuilder() {
+        if (deviceListBuilder_ == null) {
+          deviceListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder>(
+                  deviceList_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          deviceList_ = null;
+        }
+        return deviceListBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
       }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleService)
     }
-    public static final com.google.protobuf.Descriptors.Descriptor
-        getDescriptor() {
-      return policy.Policy.internal_static_policy_PolicyRule_descriptor;
+
+    // @@protoc_insertion_point(class_scope:policy.PolicyRuleService)
+    private static final policy.Policy.PolicyRuleService DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleService();
     }
 
-    @java.lang.Override
-    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-        internalGetFieldAccessorTable() {
-      return policy.Policy.internal_static_policy_PolicyRule_fieldAccessorTable
-          .ensureFieldAccessorsInitialized(
-              policy.Policy.PolicyRule.class, policy.Policy.PolicyRule.Builder.class);
+    public static policy.Policy.PolicyRuleService getDefaultInstance() {
+      return DEFAULT_INSTANCE;
     }
 
-    public static final int POLICYRULEID_FIELD_NUMBER = 1;
-    private policy.Policy.PolicyRuleId policyRuleId_;
-    /**
-     * <pre>
-     * Basic policy rule attributes
-     * </pre>
-     *
-     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
-     * @return Whether the policyRuleId field is set.
-     */
-    @java.lang.Override
-    public boolean hasPolicyRuleId() {
-      return policyRuleId_ != null;
+    private static final com.google.protobuf.Parser<PolicyRuleService>
+        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleService>() {
+      @java.lang.Override
+      public PolicyRuleService parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PolicyRuleService(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<PolicyRuleService> parser() {
+      return PARSER;
     }
-    /**
-     * <pre>
-     * Basic policy rule attributes
-     * </pre>
-     *
-     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
-     * @return The policyRuleId.
-     */
+
     @java.lang.Override
-    public policy.Policy.PolicyRuleId getPolicyRuleId() {
-      return policyRuleId_ == null ? policy.Policy.PolicyRuleId.getDefaultInstance() : policyRuleId_;
+    public com.google.protobuf.Parser<PolicyRuleService> getParserForType() {
+      return PARSER;
     }
-    /**
-     * <pre>
-     * Basic policy rule attributes
-     * </pre>
-     *
-     * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
-     */
+
     @java.lang.Override
-    public policy.Policy.PolicyRuleIdOrBuilder getPolicyRuleIdOrBuilder() {
-      return getPolicyRuleId();
+    public policy.Policy.PolicyRuleService getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
     }
 
-    public static final int POLICYRULETYPE_FIELD_NUMBER = 2;
-    private int policyRuleType_;
-    /**
-     * <code>.policy.PolicyRuleType policyRuleType = 2;</code>
-     * @return The enum numeric value on the wire for policyRuleType.
-     */
-    @java.lang.Override public int getPolicyRuleTypeValue() {
-      return policyRuleType_;
-    }
-    /**
-     * <code>.policy.PolicyRuleType policyRuleType = 2;</code>
-     * @return The policyRuleType.
-     */
-    @java.lang.Override public policy.Policy.PolicyRuleType getPolicyRuleType() {
-      @SuppressWarnings("deprecation")
-      policy.Policy.PolicyRuleType result = policy.Policy.PolicyRuleType.valueOf(policyRuleType_);
-      return result == null ? policy.Policy.PolicyRuleType.UNRECOGNIZED : result;
-    }
+  }
 
-    public static final int PRIORITY_FIELD_NUMBER = 3;
-    private int priority_;
-    /**
-     * <code>uint32 priority = 3;</code>
-     * @return The priority.
-     */
-    @java.lang.Override
-    public int getPriority() {
-      return priority_;
-    }
+  public interface PolicyRuleDeviceOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleDevice)
+      com.google.protobuf.MessageOrBuilder {
 
-    public static final int EVENT_FIELD_NUMBER = 4;
-    private policy.Policy.PolicyRuleEvent event_;
     /**
      * <pre>
-     * Event-Condition-Action model
+     * Basic policy rule attributes
      * </pre>
      *
-     * <code>.policy.PolicyRuleEvent event = 4;</code>
-     * @return Whether the event field is set.
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     * @return Whether the policyRuleBasic field is set.
      */
-    @java.lang.Override
-    public boolean hasEvent() {
-      return event_ != null;
-    }
+    boolean hasPolicyRuleBasic();
     /**
      * <pre>
-     * Event-Condition-Action model
+     * Basic policy rule attributes
      * </pre>
      *
-     * <code>.policy.PolicyRuleEvent event = 4;</code>
-     * @return The event.
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     * @return The policyRuleBasic.
      */
-    @java.lang.Override
-    public policy.Policy.PolicyRuleEvent getEvent() {
-      return event_ == null ? policy.Policy.PolicyRuleEvent.getDefaultInstance() : event_;
-    }
+    policy.Policy.PolicyRuleBasic getPolicyRuleBasic();
     /**
      * <pre>
-     * Event-Condition-Action model
+     * Basic policy rule attributes
      * </pre>
      *
-     * <code>.policy.PolicyRuleEvent event = 4;</code>
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
      */
-    @java.lang.Override
-    public policy.Policy.PolicyRuleEventOrBuilder getEventOrBuilder() {
-      return getEvent();
-    }
+    policy.Policy.PolicyRuleBasicOrBuilder getPolicyRuleBasicOrBuilder();
 
-    public static final int CONDITIONLIST_FIELD_NUMBER = 5;
-    private java.util.List<policy.PolicyCondition.PolicyRuleCondition> conditionList_;
-    /**
-     * <pre>
-     * One or more conditions must be met
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-     */
-    @java.lang.Override
-    public java.util.List<policy.PolicyCondition.PolicyRuleCondition> getConditionListList() {
-      return conditionList_;
-    }
     /**
      * <pre>
-     * One or more conditions must be met
+     * Affected device(s)
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
-    @java.lang.Override
-    public java.util.List<? extends policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
-        getConditionListOrBuilderList() {
-      return conditionList_;
-    }
+    java.util.List<context.ContextOuterClass.DeviceId> 
+        getDeviceListList();
     /**
      * <pre>
-     * One or more conditions must be met
+     * Affected device(s)
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
-    @java.lang.Override
-    public int getConditionListCount() {
-      return conditionList_.size();
-    }
+    context.ContextOuterClass.DeviceId getDeviceList(int index);
     /**
      * <pre>
-     * One or more conditions must be met
+     * Affected device(s)
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
-    @java.lang.Override
-    public policy.PolicyCondition.PolicyRuleCondition getConditionList(int index) {
-      return conditionList_.get(index);
-    }
+    int getDeviceListCount();
     /**
      * <pre>
-     * One or more conditions must be met
+     * Affected device(s)
      * </pre>
      *
-     * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
-    @java.lang.Override
-    public policy.PolicyCondition.PolicyRuleConditionOrBuilder getConditionListOrBuilder(
-        int index) {
-      return conditionList_.get(index);
-    }
-
-    public static final int BOOLEANOPERATOR_FIELD_NUMBER = 6;
-    private int booleanOperator_;
+    java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
+        getDeviceListOrBuilderList();
     /**
      * <pre>
-     * Evaluation operator to be used
+     * Affected device(s)
      * </pre>
      *
-     * <code>.policy.BooleanOperator booleanOperator = 6;</code>
-     * @return The enum numeric value on the wire for booleanOperator.
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
-    @java.lang.Override public int getBooleanOperatorValue() {
-      return booleanOperator_;
+    context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
+        int index);
+  }
+  /**
+   * <pre>
+   * Device-oriented policy rule
+   * </pre>
+   *
+   * Protobuf type {@code policy.PolicyRuleDevice}
+   */
+  public static final class PolicyRuleDevice extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:policy.PolicyRuleDevice)
+      PolicyRuleDeviceOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use PolicyRuleDevice.newBuilder() to construct.
+    private PolicyRuleDevice(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
     }
-    /**
-     * <pre>
-     * Evaluation operator to be used
-     * </pre>
-     *
-     * <code>.policy.BooleanOperator booleanOperator = 6;</code>
-     * @return The booleanOperator.
-     */
-    @java.lang.Override public policy.PolicyCondition.BooleanOperator getBooleanOperator() {
-      @SuppressWarnings("deprecation")
-      policy.PolicyCondition.BooleanOperator result = policy.PolicyCondition.BooleanOperator.valueOf(booleanOperator_);
-      return result == null ? policy.PolicyCondition.BooleanOperator.UNRECOGNIZED : result;
+    private PolicyRuleDevice() {
+      deviceList_ = java.util.Collections.emptyList();
     }
 
-    public static final int ACTIONLIST_FIELD_NUMBER = 7;
-    private java.util.List<policy.PolicyAction.PolicyRuleAction> actionList_;
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
-    @java.lang.Override
-    public java.util.List<policy.PolicyAction.PolicyRuleAction> getActionListList() {
-      return actionList_;
-    }
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
-    @java.lang.Override
-    public java.util.List<? extends policy.PolicyAction.PolicyRuleActionOrBuilder> 
-        getActionListOrBuilderList() {
-      return actionList_;
-    }
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
     @java.lang.Override
-    public int getActionListCount() {
-      return actionList_.size();
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new PolicyRuleDevice();
     }
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
+
     @java.lang.Override
-    public policy.PolicyAction.PolicyRuleAction getActionList(int index) {
-      return actionList_.get(index);
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
     }
-    /**
-     * <pre>
-     * One or more actions should be applied
-     * </pre>
-     *
-     * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-     */
+    private PolicyRuleDevice(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              policy.Policy.PolicyRuleBasic.Builder subBuilder = null;
+              if (policyRuleBasic_ != null) {
+                subBuilder = policyRuleBasic_.toBuilder();
+              }
+              policyRuleBasic_ = input.readMessage(policy.Policy.PolicyRuleBasic.parser(), extensionRegistry);
+              if (subBuilder != null) {
+                subBuilder.mergeFrom(policyRuleBasic_);
+                policyRuleBasic_ = subBuilder.buildPartial();
+              }
+
+              break;
+            }
+            case 18: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                deviceList_ = new java.util.ArrayList<context.ContextOuterClass.DeviceId>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              deviceList_.add(
+                  input.readMessage(context.ContextOuterClass.DeviceId.parser(), extensionRegistry));
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          deviceList_ = java.util.Collections.unmodifiableList(deviceList_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return policy.Policy.internal_static_policy_PolicyRuleDevice_descriptor;
+    }
+
     @java.lang.Override
-    public policy.PolicyAction.PolicyRuleActionOrBuilder getActionListOrBuilder(
-        int index) {
-      return actionList_.get(index);
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return policy.Policy.internal_static_policy_PolicyRuleDevice_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              policy.Policy.PolicyRuleDevice.class, policy.Policy.PolicyRuleDevice.Builder.class);
     }
 
-    public static final int SERVICEID_FIELD_NUMBER = 8;
-    private context.ContextOuterClass.ServiceId serviceId_;
+    public static final int POLICYRULEBASIC_FIELD_NUMBER = 1;
+    private policy.Policy.PolicyRuleBasic policyRuleBasic_;
     /**
      * <pre>
-     * Affected service and devices
+     * Basic policy rule attributes
      * </pre>
      *
-     * <code>.context.ServiceId serviceId = 8;</code>
-     * @return Whether the serviceId field is set.
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     * @return Whether the policyRuleBasic field is set.
      */
     @java.lang.Override
-    public boolean hasServiceId() {
-      return serviceId_ != null;
+    public boolean hasPolicyRuleBasic() {
+      return policyRuleBasic_ != null;
     }
     /**
      * <pre>
-     * Affected service and devices
+     * Basic policy rule attributes
      * </pre>
      *
-     * <code>.context.ServiceId serviceId = 8;</code>
-     * @return The serviceId.
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+     * @return The policyRuleBasic.
      */
     @java.lang.Override
-    public context.ContextOuterClass.ServiceId getServiceId() {
-      return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+    public policy.Policy.PolicyRuleBasic getPolicyRuleBasic() {
+      return policyRuleBasic_ == null ? policy.Policy.PolicyRuleBasic.getDefaultInstance() : policyRuleBasic_;
     }
     /**
      * <pre>
-     * Affected service and devices
+     * Basic policy rule attributes
      * </pre>
      *
-     * <code>.context.ServiceId serviceId = 8;</code>
+     * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
      */
     @java.lang.Override
-    public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-      return getServiceId();
+    public policy.Policy.PolicyRuleBasicOrBuilder getPolicyRuleBasicOrBuilder() {
+      return getPolicyRuleBasic();
     }
 
-    public static final int DEVICELIST_FIELD_NUMBER = 9;
+    public static final int DEVICELIST_FIELD_NUMBER = 2;
     private java.util.List<context.ContextOuterClass.DeviceId> deviceList_;
     /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
+     * <pre>
+     * Affected device(s)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
     @java.lang.Override
     public java.util.List<context.ContextOuterClass.DeviceId> getDeviceListList() {
       return deviceList_;
     }
     /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
+     * <pre>
+     * Affected device(s)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
     @java.lang.Override
     public java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
@@ -2985,21 +5147,33 @@ public final class Policy {
       return deviceList_;
     }
     /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
+     * <pre>
+     * Affected device(s)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
     @java.lang.Override
     public int getDeviceListCount() {
       return deviceList_.size();
     }
     /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
+     * <pre>
+     * Affected device(s)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.DeviceId getDeviceList(int index) {
       return deviceList_.get(index);
     }
     /**
-     * <code>repeated .context.DeviceId deviceList = 9;</code>
+     * <pre>
+     * Affected device(s)
+     * </pre>
+     *
+     * <code>repeated .context.DeviceId deviceList = 2;</code>
      */
     @java.lang.Override
     public context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
@@ -3021,32 +5195,11 @@ public final class Policy {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      if (policyRuleId_ != null) {
-        output.writeMessage(1, getPolicyRuleId());
-      }
-      if (policyRuleType_ != policy.Policy.PolicyRuleType.POLICYTYPE_DEVICE.getNumber()) {
-        output.writeEnum(2, policyRuleType_);
-      }
-      if (priority_ != 0) {
-        output.writeUInt32(3, priority_);
-      }
-      if (event_ != null) {
-        output.writeMessage(4, getEvent());
-      }
-      for (int i = 0; i < conditionList_.size(); i++) {
-        output.writeMessage(5, conditionList_.get(i));
-      }
-      if (booleanOperator_ != policy.PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED.getNumber()) {
-        output.writeEnum(6, booleanOperator_);
-      }
-      for (int i = 0; i < actionList_.size(); i++) {
-        output.writeMessage(7, actionList_.get(i));
-      }
-      if (serviceId_ != null) {
-        output.writeMessage(8, getServiceId());
+      if (policyRuleBasic_ != null) {
+        output.writeMessage(1, getPolicyRuleBasic());
       }
       for (int i = 0; i < deviceList_.size(); i++) {
-        output.writeMessage(9, deviceList_.get(i));
+        output.writeMessage(2, deviceList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -3057,41 +5210,13 @@ public final class Policy {
       if (size != -1) return size;
 
       size = 0;
-      if (policyRuleId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, getPolicyRuleId());
-      }
-      if (policyRuleType_ != policy.Policy.PolicyRuleType.POLICYTYPE_DEVICE.getNumber()) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(2, policyRuleType_);
-      }
-      if (priority_ != 0) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeUInt32Size(3, priority_);
-      }
-      if (event_ != null) {
+      if (policyRuleBasic_ != null) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(4, getEvent());
-      }
-      for (int i = 0; i < conditionList_.size(); i++) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(5, conditionList_.get(i));
-      }
-      if (booleanOperator_ != policy.PolicyCondition.BooleanOperator.POLICYRULE_CONDITION_BOOLEAN_UNDEFINED.getNumber()) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeEnumSize(6, booleanOperator_);
-      }
-      for (int i = 0; i < actionList_.size(); i++) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(7, actionList_.get(i));
-      }
-      if (serviceId_ != null) {
-        size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(8, getServiceId());
+          .computeMessageSize(1, getPolicyRuleBasic());
       }
       for (int i = 0; i < deviceList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(9, deviceList_.get(i));
+          .computeMessageSize(2, deviceList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -3103,33 +5228,15 @@ public final class Policy {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof policy.Policy.PolicyRule)) {
+      if (!(obj instanceof policy.Policy.PolicyRuleDevice)) {
         return super.equals(obj);
       }
-      policy.Policy.PolicyRule other = (policy.Policy.PolicyRule) obj;
+      policy.Policy.PolicyRuleDevice other = (policy.Policy.PolicyRuleDevice) obj;
 
-      if (hasPolicyRuleId() != other.hasPolicyRuleId()) return false;
-      if (hasPolicyRuleId()) {
-        if (!getPolicyRuleId()
-            .equals(other.getPolicyRuleId())) return false;
-      }
-      if (policyRuleType_ != other.policyRuleType_) return false;
-      if (getPriority()
-          != other.getPriority()) return false;
-      if (hasEvent() != other.hasEvent()) return false;
-      if (hasEvent()) {
-        if (!getEvent()
-            .equals(other.getEvent())) return false;
-      }
-      if (!getConditionListList()
-          .equals(other.getConditionListList())) return false;
-      if (booleanOperator_ != other.booleanOperator_) return false;
-      if (!getActionListList()
-          .equals(other.getActionListList())) return false;
-      if (hasServiceId() != other.hasServiceId()) return false;
-      if (hasServiceId()) {
-        if (!getServiceId()
-            .equals(other.getServiceId())) return false;
+      if (hasPolicyRuleBasic() != other.hasPolicyRuleBasic()) return false;
+      if (hasPolicyRuleBasic()) {
+        if (!getPolicyRuleBasic()
+            .equals(other.getPolicyRuleBasic())) return false;
       }
       if (!getDeviceListList()
           .equals(other.getDeviceListList())) return false;
@@ -3144,31 +5251,9 @@ public final class Policy {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (hasPolicyRuleId()) {
-        hash = (37 * hash) + POLICYRULEID_FIELD_NUMBER;
-        hash = (53 * hash) + getPolicyRuleId().hashCode();
-      }
-      hash = (37 * hash) + POLICYRULETYPE_FIELD_NUMBER;
-      hash = (53 * hash) + policyRuleType_;
-      hash = (37 * hash) + PRIORITY_FIELD_NUMBER;
-      hash = (53 * hash) + getPriority();
-      if (hasEvent()) {
-        hash = (37 * hash) + EVENT_FIELD_NUMBER;
-        hash = (53 * hash) + getEvent().hashCode();
-      }
-      if (getConditionListCount() > 0) {
-        hash = (37 * hash) + CONDITIONLIST_FIELD_NUMBER;
-        hash = (53 * hash) + getConditionListList().hashCode();
-      }
-      hash = (37 * hash) + BOOLEANOPERATOR_FIELD_NUMBER;
-      hash = (53 * hash) + booleanOperator_;
-      if (getActionListCount() > 0) {
-        hash = (37 * hash) + ACTIONLIST_FIELD_NUMBER;
-        hash = (53 * hash) + getActionListList().hashCode();
-      }
-      if (hasServiceId()) {
-        hash = (37 * hash) + SERVICEID_FIELD_NUMBER;
-        hash = (53 * hash) + getServiceId().hashCode();
+      if (hasPolicyRuleBasic()) {
+        hash = (37 * hash) + POLICYRULEBASIC_FIELD_NUMBER;
+        hash = (53 * hash) + getPolicyRuleBasic().hashCode();
       }
       if (getDeviceListCount() > 0) {
         hash = (37 * hash) + DEVICELIST_FIELD_NUMBER;
@@ -3179,69 +5264,69 @@ public final class Policy {
       return hash;
     }
 
-    public static policy.Policy.PolicyRule parseFrom(
+    public static policy.Policy.PolicyRuleDevice parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRule parseFrom(
+    public static policy.Policy.PolicyRuleDevice parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRule parseFrom(
+    public static policy.Policy.PolicyRuleDevice parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRule parseFrom(
+    public static policy.Policy.PolicyRuleDevice parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRule parseFrom(byte[] data)
+    public static policy.Policy.PolicyRuleDevice parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRule parseFrom(
+    public static policy.Policy.PolicyRuleDevice parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRule parseFrom(java.io.InputStream input)
+    public static policy.Policy.PolicyRuleDevice parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRule parseFrom(
+    public static policy.Policy.PolicyRuleDevice parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input, extensionRegistry);
     }
-    public static policy.Policy.PolicyRule parseDelimitedFrom(java.io.InputStream input)
+    public static policy.Policy.PolicyRuleDevice parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRule parseDelimitedFrom(
+    public static policy.Policy.PolicyRuleDevice parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
-    public static policy.Policy.PolicyRule parseFrom(
+    public static policy.Policy.PolicyRuleDevice parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRule parseFrom(
+    public static policy.Policy.PolicyRuleDevice parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -3254,7 +5339,7 @@ public final class Policy {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(policy.Policy.PolicyRule prototype) {
+    public static Builder newBuilder(policy.Policy.PolicyRuleDevice prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -3271,32 +5356,29 @@ public final class Policy {
     }
     /**
      * <pre>
-     * Policy rule partially complies with IETF’s:
-     *     RFC 3060: https://datatracker.ietf.org/doc/html/rfc3060
-     *     RFC 3460: https://datatracker.ietf.org/doc/html/rfc3460
-     * Enhanced with a policy rule event according to the ECA model
+     * Device-oriented policy rule
      * </pre>
      *
-     * Protobuf type {@code policy.PolicyRule}
+     * Protobuf type {@code policy.PolicyRuleDevice}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:policy.PolicyRule)
-        policy.Policy.PolicyRuleOrBuilder {
+        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleDevice)
+        policy.Policy.PolicyRuleDeviceOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return policy.Policy.internal_static_policy_PolicyRule_descriptor;
+        return policy.Policy.internal_static_policy_PolicyRuleDevice_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return policy.Policy.internal_static_policy_PolicyRule_fieldAccessorTable
+        return policy.Policy.internal_static_policy_PolicyRuleDevice_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                policy.Policy.PolicyRule.class, policy.Policy.PolicyRule.Builder.class);
+                policy.Policy.PolicyRuleDevice.class, policy.Policy.PolicyRuleDevice.Builder.class);
       }
 
-      // Construct using policy.Policy.PolicyRule.newBuilder()
+      // Construct using policy.Policy.PolicyRuleDevice.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -3309,53 +5391,21 @@ public final class Policy {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getConditionListFieldBuilder();
-          getActionListFieldBuilder();
           getDeviceListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (policyRuleIdBuilder_ == null) {
-          policyRuleId_ = null;
-        } else {
-          policyRuleId_ = null;
-          policyRuleIdBuilder_ = null;
-        }
-        policyRuleType_ = 0;
-
-        priority_ = 0;
-
-        if (eventBuilder_ == null) {
-          event_ = null;
-        } else {
-          event_ = null;
-          eventBuilder_ = null;
-        }
-        if (conditionListBuilder_ == null) {
-          conditionList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000001);
-        } else {
-          conditionListBuilder_.clear();
-        }
-        booleanOperator_ = 0;
-
-        if (actionListBuilder_ == null) {
-          actionList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000002);
-        } else {
-          actionListBuilder_.clear();
-        }
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = null;
+        if (policyRuleBasicBuilder_ == null) {
+          policyRuleBasic_ = null;
         } else {
-          serviceId_ = null;
-          serviceIdBuilder_ = null;
+          policyRuleBasic_ = null;
+          policyRuleBasicBuilder_ = null;
         }
         if (deviceListBuilder_ == null) {
           deviceList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000004);
+          bitField0_ = (bitField0_ & ~0x00000001);
         } else {
           deviceListBuilder_.clear();
         }
@@ -3365,17 +5415,17 @@ public final class Policy {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return policy.Policy.internal_static_policy_PolicyRule_descriptor;
+        return policy.Policy.internal_static_policy_PolicyRuleDevice_descriptor;
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRule getDefaultInstanceForType() {
-        return policy.Policy.PolicyRule.getDefaultInstance();
+      public policy.Policy.PolicyRuleDevice getDefaultInstanceForType() {
+        return policy.Policy.PolicyRuleDevice.getDefaultInstance();
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRule build() {
-        policy.Policy.PolicyRule result = buildPartial();
+      public policy.Policy.PolicyRuleDevice build() {
+        policy.Policy.PolicyRuleDevice result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -3383,49 +5433,18 @@ public final class Policy {
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRule buildPartial() {
-        policy.Policy.PolicyRule result = new policy.Policy.PolicyRule(this);
+      public policy.Policy.PolicyRuleDevice buildPartial() {
+        policy.Policy.PolicyRuleDevice result = new policy.Policy.PolicyRuleDevice(this);
         int from_bitField0_ = bitField0_;
-        if (policyRuleIdBuilder_ == null) {
-          result.policyRuleId_ = policyRuleId_;
-        } else {
-          result.policyRuleId_ = policyRuleIdBuilder_.build();
-        }
-        result.policyRuleType_ = policyRuleType_;
-        result.priority_ = priority_;
-        if (eventBuilder_ == null) {
-          result.event_ = event_;
-        } else {
-          result.event_ = eventBuilder_.build();
-        }
-        if (conditionListBuilder_ == null) {
-          if (((bitField0_ & 0x00000001) != 0)) {
-            conditionList_ = java.util.Collections.unmodifiableList(conditionList_);
-            bitField0_ = (bitField0_ & ~0x00000001);
-          }
-          result.conditionList_ = conditionList_;
+        if (policyRuleBasicBuilder_ == null) {
+          result.policyRuleBasic_ = policyRuleBasic_;
         } else {
-          result.conditionList_ = conditionListBuilder_.build();
-        }
-        result.booleanOperator_ = booleanOperator_;
-        if (actionListBuilder_ == null) {
-          if (((bitField0_ & 0x00000002) != 0)) {
-            actionList_ = java.util.Collections.unmodifiableList(actionList_);
-            bitField0_ = (bitField0_ & ~0x00000002);
-          }
-          result.actionList_ = actionList_;
-        } else {
-          result.actionList_ = actionListBuilder_.build();
-        }
-        if (serviceIdBuilder_ == null) {
-          result.serviceId_ = serviceId_;
-        } else {
-          result.serviceId_ = serviceIdBuilder_.build();
+          result.policyRuleBasic_ = policyRuleBasicBuilder_.build();
         }
         if (deviceListBuilder_ == null) {
-          if (((bitField0_ & 0x00000004) != 0)) {
+          if (((bitField0_ & 0x00000001) != 0)) {
             deviceList_ = java.util.Collections.unmodifiableList(deviceList_);
-            bitField0_ = (bitField0_ & ~0x00000004);
+            bitField0_ = (bitField0_ & ~0x00000001);
           }
           result.deviceList_ = deviceList_;
         } else {
@@ -3461,99 +5480,32 @@ public final class Policy {
           int index, java.lang.Object value) {
         return super.setRepeatedField(field, index, value);
       }
-      @java.lang.Override
-      public Builder addRepeatedField(
-          com.google.protobuf.Descriptors.FieldDescriptor field,
-          java.lang.Object value) {
-        return super.addRepeatedField(field, value);
-      }
-      @java.lang.Override
-      public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof policy.Policy.PolicyRule) {
-          return mergeFrom((policy.Policy.PolicyRule)other);
-        } else {
-          super.mergeFrom(other);
-          return this;
-        }
-      }
-
-      public Builder mergeFrom(policy.Policy.PolicyRule other) {
-        if (other == policy.Policy.PolicyRule.getDefaultInstance()) return this;
-        if (other.hasPolicyRuleId()) {
-          mergePolicyRuleId(other.getPolicyRuleId());
-        }
-        if (other.policyRuleType_ != 0) {
-          setPolicyRuleTypeValue(other.getPolicyRuleTypeValue());
-        }
-        if (other.getPriority() != 0) {
-          setPriority(other.getPriority());
-        }
-        if (other.hasEvent()) {
-          mergeEvent(other.getEvent());
-        }
-        if (conditionListBuilder_ == null) {
-          if (!other.conditionList_.isEmpty()) {
-            if (conditionList_.isEmpty()) {
-              conditionList_ = other.conditionList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-            } else {
-              ensureConditionListIsMutable();
-              conditionList_.addAll(other.conditionList_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.conditionList_.isEmpty()) {
-            if (conditionListBuilder_.isEmpty()) {
-              conditionListBuilder_.dispose();
-              conditionListBuilder_ = null;
-              conditionList_ = other.conditionList_;
-              bitField0_ = (bitField0_ & ~0x00000001);
-              conditionListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getConditionListFieldBuilder() : null;
-            } else {
-              conditionListBuilder_.addAllMessages(other.conditionList_);
-            }
-          }
-        }
-        if (other.booleanOperator_ != 0) {
-          setBooleanOperatorValue(other.getBooleanOperatorValue());
-        }
-        if (actionListBuilder_ == null) {
-          if (!other.actionList_.isEmpty()) {
-            if (actionList_.isEmpty()) {
-              actionList_ = other.actionList_;
-              bitField0_ = (bitField0_ & ~0x00000002);
-            } else {
-              ensureActionListIsMutable();
-              actionList_.addAll(other.actionList_);
-            }
-            onChanged();
-          }
-        } else {
-          if (!other.actionList_.isEmpty()) {
-            if (actionListBuilder_.isEmpty()) {
-              actionListBuilder_.dispose();
-              actionListBuilder_ = null;
-              actionList_ = other.actionList_;
-              bitField0_ = (bitField0_ & ~0x00000002);
-              actionListBuilder_ = 
-                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getActionListFieldBuilder() : null;
-            } else {
-              actionListBuilder_.addAllMessages(other.actionList_);
-            }
-          }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof policy.Policy.PolicyRuleDevice) {
+          return mergeFrom((policy.Policy.PolicyRuleDevice)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
         }
-        if (other.hasServiceId()) {
-          mergeServiceId(other.getServiceId());
+      }
+
+      public Builder mergeFrom(policy.Policy.PolicyRuleDevice other) {
+        if (other == policy.Policy.PolicyRuleDevice.getDefaultInstance()) return this;
+        if (other.hasPolicyRuleBasic()) {
+          mergePolicyRuleBasic(other.getPolicyRuleBasic());
         }
         if (deviceListBuilder_ == null) {
           if (!other.deviceList_.isEmpty()) {
             if (deviceList_.isEmpty()) {
               deviceList_ = other.deviceList_;
-              bitField0_ = (bitField0_ & ~0x00000004);
+              bitField0_ = (bitField0_ & ~0x00000001);
             } else {
               ensureDeviceListIsMutable();
               deviceList_.addAll(other.deviceList_);
@@ -3566,7 +5518,7 @@ public final class Policy {
               deviceListBuilder_.dispose();
               deviceListBuilder_ = null;
               deviceList_ = other.deviceList_;
-              bitField0_ = (bitField0_ & ~0x00000004);
+              bitField0_ = (bitField0_ & ~0x00000001);
               deviceListBuilder_ = 
                 com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
                    getDeviceListFieldBuilder() : null;
@@ -3590,11 +5542,11 @@ public final class Policy {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        policy.Policy.PolicyRule parsedMessage = null;
+        policy.Policy.PolicyRuleDevice parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (policy.Policy.PolicyRule) e.getUnfinishedMessage();
+          parsedMessage = (policy.Policy.PolicyRuleDevice) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -3605,33 +5557,33 @@ public final class Policy {
       }
       private int bitField0_;
 
-      private policy.Policy.PolicyRuleId policyRuleId_;
+      private policy.Policy.PolicyRuleBasic policyRuleBasic_;
       private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleId.Builder, policy.Policy.PolicyRuleIdOrBuilder> policyRuleIdBuilder_;
+          policy.Policy.PolicyRuleBasic, policy.Policy.PolicyRuleBasic.Builder, policy.Policy.PolicyRuleBasicOrBuilder> policyRuleBasicBuilder_;
       /**
        * <pre>
        * Basic policy rule attributes
        * </pre>
        *
-       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
-       * @return Whether the policyRuleId field is set.
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       * @return Whether the policyRuleBasic field is set.
        */
-      public boolean hasPolicyRuleId() {
-        return policyRuleIdBuilder_ != null || policyRuleId_ != null;
+      public boolean hasPolicyRuleBasic() {
+        return policyRuleBasicBuilder_ != null || policyRuleBasic_ != null;
       }
       /**
        * <pre>
        * Basic policy rule attributes
        * </pre>
        *
-       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
-       * @return The policyRuleId.
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       * @return The policyRuleBasic.
        */
-      public policy.Policy.PolicyRuleId getPolicyRuleId() {
-        if (policyRuleIdBuilder_ == null) {
-          return policyRuleId_ == null ? policy.Policy.PolicyRuleId.getDefaultInstance() : policyRuleId_;
+      public policy.Policy.PolicyRuleBasic getPolicyRuleBasic() {
+        if (policyRuleBasicBuilder_ == null) {
+          return policyRuleBasic_ == null ? policy.Policy.PolicyRuleBasic.getDefaultInstance() : policyRuleBasic_;
         } else {
-          return policyRuleIdBuilder_.getMessage();
+          return policyRuleBasicBuilder_.getMessage();
         }
       }
       /**
@@ -3639,1458 +5591,2039 @@ public final class Policy {
        * Basic policy rule attributes
        * </pre>
        *
-       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
        */
-      public Builder setPolicyRuleId(policy.Policy.PolicyRuleId value) {
-        if (policyRuleIdBuilder_ == null) {
+      public Builder setPolicyRuleBasic(policy.Policy.PolicyRuleBasic value) {
+        if (policyRuleBasicBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          policyRuleId_ = value;
+          policyRuleBasic_ = value;
           onChanged();
         } else {
-          policyRuleIdBuilder_.setMessage(value);
+          policyRuleBasicBuilder_.setMessage(value);
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public Builder setPolicyRuleBasic(
+          policy.Policy.PolicyRuleBasic.Builder builderForValue) {
+        if (policyRuleBasicBuilder_ == null) {
+          policyRuleBasic_ = builderForValue.build();
+          onChanged();
+        } else {
+          policyRuleBasicBuilder_.setMessage(builderForValue.build());
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public Builder mergePolicyRuleBasic(policy.Policy.PolicyRuleBasic value) {
+        if (policyRuleBasicBuilder_ == null) {
+          if (policyRuleBasic_ != null) {
+            policyRuleBasic_ =
+              policy.Policy.PolicyRuleBasic.newBuilder(policyRuleBasic_).mergeFrom(value).buildPartial();
+          } else {
+            policyRuleBasic_ = value;
+          }
+          onChanged();
+        } else {
+          policyRuleBasicBuilder_.mergeFrom(value);
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public Builder clearPolicyRuleBasic() {
+        if (policyRuleBasicBuilder_ == null) {
+          policyRuleBasic_ = null;
+          onChanged();
+        } else {
+          policyRuleBasic_ = null;
+          policyRuleBasicBuilder_ = null;
+        }
+
+        return this;
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public policy.Policy.PolicyRuleBasic.Builder getPolicyRuleBasicBuilder() {
+        
+        onChanged();
+        return getPolicyRuleBasicFieldBuilder().getBuilder();
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      public policy.Policy.PolicyRuleBasicOrBuilder getPolicyRuleBasicOrBuilder() {
+        if (policyRuleBasicBuilder_ != null) {
+          return policyRuleBasicBuilder_.getMessageOrBuilder();
+        } else {
+          return policyRuleBasic_ == null ?
+              policy.Policy.PolicyRuleBasic.getDefaultInstance() : policyRuleBasic_;
+        }
+      }
+      /**
+       * <pre>
+       * Basic policy rule attributes
+       * </pre>
+       *
+       * <code>.policy.PolicyRuleBasic policyRuleBasic = 1;</code>
+       */
+      private com.google.protobuf.SingleFieldBuilderV3<
+          policy.Policy.PolicyRuleBasic, policy.Policy.PolicyRuleBasic.Builder, policy.Policy.PolicyRuleBasicOrBuilder> 
+          getPolicyRuleBasicFieldBuilder() {
+        if (policyRuleBasicBuilder_ == null) {
+          policyRuleBasicBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
+              policy.Policy.PolicyRuleBasic, policy.Policy.PolicyRuleBasic.Builder, policy.Policy.PolicyRuleBasicOrBuilder>(
+                  getPolicyRuleBasic(),
+                  getParentForChildren(),
+                  isClean());
+          policyRuleBasic_ = null;
+        }
+        return policyRuleBasicBuilder_;
+      }
+
+      private java.util.List<context.ContextOuterClass.DeviceId> deviceList_ =
+        java.util.Collections.emptyList();
+      private void ensureDeviceListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          deviceList_ = new java.util.ArrayList<context.ContextOuterClass.DeviceId>(deviceList_);
+          bitField0_ |= 0x00000001;
+         }
+      }
+
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder> deviceListBuilder_;
+
+      /**
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
+       */
+      public java.util.List<context.ContextOuterClass.DeviceId> getDeviceListList() {
+        if (deviceListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(deviceList_);
+        } else {
+          return deviceListBuilder_.getMessageList();
+        }
+      }
+      /**
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
+       */
+      public int getDeviceListCount() {
+        if (deviceListBuilder_ == null) {
+          return deviceList_.size();
+        } else {
+          return deviceListBuilder_.getCount();
+        }
+      }
+      /**
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
+       */
+      public context.ContextOuterClass.DeviceId getDeviceList(int index) {
+        if (deviceListBuilder_ == null) {
+          return deviceList_.get(index);
+        } else {
+          return deviceListBuilder_.getMessage(index);
+        }
+      }
+      /**
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
+       */
+      public Builder setDeviceList(
+          int index, context.ContextOuterClass.DeviceId value) {
+        if (deviceListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureDeviceListIsMutable();
+          deviceList_.set(index, value);
+          onChanged();
+        } else {
+          deviceListBuilder_.setMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
+       */
+      public Builder setDeviceList(
+          int index, context.ContextOuterClass.DeviceId.Builder builderForValue) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          deviceList_.set(index, builderForValue.build());
+          onChanged();
+        } else {
+          deviceListBuilder_.setMessage(index, builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
+       */
+      public Builder addDeviceList(context.ContextOuterClass.DeviceId value) {
+        if (deviceListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureDeviceListIsMutable();
+          deviceList_.add(value);
+          onChanged();
+        } else {
+          deviceListBuilder_.addMessage(value);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
+       */
+      public Builder addDeviceList(
+          int index, context.ContextOuterClass.DeviceId value) {
+        if (deviceListBuilder_ == null) {
+          if (value == null) {
+            throw new NullPointerException();
+          }
+          ensureDeviceListIsMutable();
+          deviceList_.add(index, value);
+          onChanged();
+        } else {
+          deviceListBuilder_.addMessage(index, value);
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
+       */
+      public Builder addDeviceList(
+          context.ContextOuterClass.DeviceId.Builder builderForValue) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          deviceList_.add(builderForValue.build());
+          onChanged();
+        } else {
+          deviceListBuilder_.addMessage(builderForValue.build());
+        }
+        return this;
+      }
+      /**
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
+       */
+      public Builder addDeviceList(
+          int index, context.ContextOuterClass.DeviceId.Builder builderForValue) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          deviceList_.add(index, builderForValue.build());
+          onChanged();
+        } else {
+          deviceListBuilder_.addMessage(index, builderForValue.build());
         }
-
         return this;
       }
       /**
        * <pre>
-       * Basic policy rule attributes
+       * Affected device(s)
        * </pre>
        *
-       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
        */
-      public Builder setPolicyRuleId(
-          policy.Policy.PolicyRuleId.Builder builderForValue) {
-        if (policyRuleIdBuilder_ == null) {
-          policyRuleId_ = builderForValue.build();
+      public Builder addAllDeviceList(
+          java.lang.Iterable<? extends context.ContextOuterClass.DeviceId> values) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          com.google.protobuf.AbstractMessageLite.Builder.addAll(
+              values, deviceList_);
           onChanged();
         } else {
-          policyRuleIdBuilder_.setMessage(builderForValue.build());
+          deviceListBuilder_.addAllMessages(values);
         }
-
         return this;
       }
       /**
        * <pre>
-       * Basic policy rule attributes
+       * Affected device(s)
        * </pre>
        *
-       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
        */
-      public Builder mergePolicyRuleId(policy.Policy.PolicyRuleId value) {
-        if (policyRuleIdBuilder_ == null) {
-          if (policyRuleId_ != null) {
-            policyRuleId_ =
-              policy.Policy.PolicyRuleId.newBuilder(policyRuleId_).mergeFrom(value).buildPartial();
-          } else {
-            policyRuleId_ = value;
-          }
+      public Builder clearDeviceList() {
+        if (deviceListBuilder_ == null) {
+          deviceList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          policyRuleIdBuilder_.mergeFrom(value);
+          deviceListBuilder_.clear();
         }
-
         return this;
       }
       /**
        * <pre>
-       * Basic policy rule attributes
+       * Affected device(s)
        * </pre>
        *
-       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
        */
-      public Builder clearPolicyRuleId() {
-        if (policyRuleIdBuilder_ == null) {
-          policyRuleId_ = null;
+      public Builder removeDeviceList(int index) {
+        if (deviceListBuilder_ == null) {
+          ensureDeviceListIsMutable();
+          deviceList_.remove(index);
           onChanged();
         } else {
-          policyRuleId_ = null;
-          policyRuleIdBuilder_ = null;
+          deviceListBuilder_.remove(index);
         }
-
         return this;
       }
       /**
        * <pre>
-       * Basic policy rule attributes
+       * Affected device(s)
        * </pre>
        *
-       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
        */
-      public policy.Policy.PolicyRuleId.Builder getPolicyRuleIdBuilder() {
-        
-        onChanged();
-        return getPolicyRuleIdFieldBuilder().getBuilder();
+      public context.ContextOuterClass.DeviceId.Builder getDeviceListBuilder(
+          int index) {
+        return getDeviceListFieldBuilder().getBuilder(index);
       }
       /**
        * <pre>
-       * Basic policy rule attributes
+       * Affected device(s)
        * </pre>
        *
-       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
        */
-      public policy.Policy.PolicyRuleIdOrBuilder getPolicyRuleIdOrBuilder() {
-        if (policyRuleIdBuilder_ != null) {
-          return policyRuleIdBuilder_.getMessageOrBuilder();
-        } else {
-          return policyRuleId_ == null ?
-              policy.Policy.PolicyRuleId.getDefaultInstance() : policyRuleId_;
+      public context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
+          int index) {
+        if (deviceListBuilder_ == null) {
+          return deviceList_.get(index);  } else {
+          return deviceListBuilder_.getMessageOrBuilder(index);
         }
       }
       /**
        * <pre>
-       * Basic policy rule attributes
+       * Affected device(s)
        * </pre>
        *
-       * <code>.policy.PolicyRuleId policyRuleId = 1;</code>
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
        */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleId.Builder, policy.Policy.PolicyRuleIdOrBuilder> 
-          getPolicyRuleIdFieldBuilder() {
-        if (policyRuleIdBuilder_ == null) {
-          policyRuleIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleId.Builder, policy.Policy.PolicyRuleIdOrBuilder>(
-                  getPolicyRuleId(),
-                  getParentForChildren(),
-                  isClean());
-          policyRuleId_ = null;
+      public java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
+           getDeviceListOrBuilderList() {
+        if (deviceListBuilder_ != null) {
+          return deviceListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(deviceList_);
         }
-        return policyRuleIdBuilder_;
       }
-
-      private int policyRuleType_ = 0;
       /**
-       * <code>.policy.PolicyRuleType policyRuleType = 2;</code>
-       * @return The enum numeric value on the wire for policyRuleType.
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
        */
-      @java.lang.Override public int getPolicyRuleTypeValue() {
-        return policyRuleType_;
+      public context.ContextOuterClass.DeviceId.Builder addDeviceListBuilder() {
+        return getDeviceListFieldBuilder().addBuilder(
+            context.ContextOuterClass.DeviceId.getDefaultInstance());
       }
       /**
-       * <code>.policy.PolicyRuleType policyRuleType = 2;</code>
-       * @param value The enum numeric value on the wire for policyRuleType to set.
-       * @return This builder for chaining.
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
        */
-      public Builder setPolicyRuleTypeValue(int value) {
-        
-        policyRuleType_ = value;
-        onChanged();
-        return this;
+      public context.ContextOuterClass.DeviceId.Builder addDeviceListBuilder(
+          int index) {
+        return getDeviceListFieldBuilder().addBuilder(
+            index, context.ContextOuterClass.DeviceId.getDefaultInstance());
       }
       /**
-       * <code>.policy.PolicyRuleType policyRuleType = 2;</code>
-       * @return The policyRuleType.
+       * <pre>
+       * Affected device(s)
+       * </pre>
+       *
+       * <code>repeated .context.DeviceId deviceList = 2;</code>
        */
-      @java.lang.Override
-      public policy.Policy.PolicyRuleType getPolicyRuleType() {
-        @SuppressWarnings("deprecation")
-        policy.Policy.PolicyRuleType result = policy.Policy.PolicyRuleType.valueOf(policyRuleType_);
-        return result == null ? policy.Policy.PolicyRuleType.UNRECOGNIZED : result;
+      public java.util.List<context.ContextOuterClass.DeviceId.Builder> 
+           getDeviceListBuilderList() {
+        return getDeviceListFieldBuilder().getBuilderList();
       }
-      /**
-       * <code>.policy.PolicyRuleType policyRuleType = 2;</code>
-       * @param value The policyRuleType to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPolicyRuleType(policy.Policy.PolicyRuleType value) {
-        if (value == null) {
-          throw new NullPointerException();
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder> 
+          getDeviceListFieldBuilder() {
+        if (deviceListBuilder_ == null) {
+          deviceListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder>(
+                  deviceList_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          deviceList_ = null;
         }
-        
-        policyRuleType_ = value.getNumber();
-        onChanged();
-        return this;
+        return deviceListBuilder_;
       }
-      /**
-       * <code>.policy.PolicyRuleType policyRuleType = 2;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPolicyRuleType() {
-        
-        policyRuleType_ = 0;
-        onChanged();
-        return this;
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
       }
 
-      private int priority_ ;
-      /**
-       * <code>uint32 priority = 3;</code>
-       * @return The priority.
-       */
       @java.lang.Override
-      public int getPriority() {
-        return priority_;
-      }
-      /**
-       * <code>uint32 priority = 3;</code>
-       * @param value The priority to set.
-       * @return This builder for chaining.
-       */
-      public Builder setPriority(int value) {
-        
-        priority_ = value;
-        onChanged();
-        return this;
-      }
-      /**
-       * <code>uint32 priority = 3;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearPriority() {
-        
-        priority_ = 0;
-        onChanged();
-        return this;
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
       }
 
-      private policy.Policy.PolicyRuleEvent event_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleEvent, policy.Policy.PolicyRuleEvent.Builder, policy.Policy.PolicyRuleEventOrBuilder> eventBuilder_;
-      /**
-       * <pre>
-       * Event-Condition-Action model
-       * </pre>
-       *
-       * <code>.policy.PolicyRuleEvent event = 4;</code>
-       * @return Whether the event field is set.
-       */
-      public boolean hasEvent() {
-        return eventBuilder_ != null || event_ != null;
+
+      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleDevice)
+    }
+
+    // @@protoc_insertion_point(class_scope:policy.PolicyRuleDevice)
+    private static final policy.Policy.PolicyRuleDevice DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleDevice();
+    }
+
+    public static policy.Policy.PolicyRuleDevice getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<PolicyRuleDevice>
+        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleDevice>() {
+      @java.lang.Override
+      public PolicyRuleDevice parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PolicyRuleDevice(input, extensionRegistry);
       }
-      /**
-       * <pre>
-       * Event-Condition-Action model
-       * </pre>
-       *
-       * <code>.policy.PolicyRuleEvent event = 4;</code>
-       * @return The event.
-       */
-      public policy.Policy.PolicyRuleEvent getEvent() {
-        if (eventBuilder_ == null) {
-          return event_ == null ? policy.Policy.PolicyRuleEvent.getDefaultInstance() : event_;
-        } else {
-          return eventBuilder_.getMessage();
-        }
+    };
+
+    public static com.google.protobuf.Parser<PolicyRuleDevice> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PolicyRuleDevice> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public policy.Policy.PolicyRuleDevice getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface PolicyRuleIdListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleIdList)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    java.util.List<policy.Policy.PolicyRuleId> 
+        getPolicyRuleIdListList();
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    policy.Policy.PolicyRuleId getPolicyRuleIdList(int index);
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    int getPolicyRuleIdListCount();
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    java.util.List<? extends policy.Policy.PolicyRuleIdOrBuilder> 
+        getPolicyRuleIdListOrBuilderList();
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    policy.Policy.PolicyRuleIdOrBuilder getPolicyRuleIdListOrBuilder(
+        int index);
+  }
+  /**
+   * <pre>
+   * A list of policy rule IDs
+   * </pre>
+   *
+   * Protobuf type {@code policy.PolicyRuleIdList}
+   */
+  public static final class PolicyRuleIdList extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:policy.PolicyRuleIdList)
+      PolicyRuleIdListOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use PolicyRuleIdList.newBuilder() to construct.
+    private PolicyRuleIdList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private PolicyRuleIdList() {
+      policyRuleIdList_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new PolicyRuleIdList();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PolicyRuleIdList(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
       }
-      /**
-       * <pre>
-       * Event-Condition-Action model
-       * </pre>
-       *
-       * <code>.policy.PolicyRuleEvent event = 4;</code>
-       */
-      public Builder setEvent(policy.Policy.PolicyRuleEvent value) {
-        if (eventBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                policyRuleIdList_ = new java.util.ArrayList<policy.Policy.PolicyRuleId>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              policyRuleIdList_.add(
+                  input.readMessage(policy.Policy.PolicyRuleId.parser(), extensionRegistry));
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
           }
-          event_ = value;
-          onChanged();
-        } else {
-          eventBuilder_.setMessage(value);
         }
-
-        return this;
-      }
-      /**
-       * <pre>
-       * Event-Condition-Action model
-       * </pre>
-       *
-       * <code>.policy.PolicyRuleEvent event = 4;</code>
-       */
-      public Builder setEvent(
-          policy.Policy.PolicyRuleEvent.Builder builderForValue) {
-        if (eventBuilder_ == null) {
-          event_ = builderForValue.build();
-          onChanged();
-        } else {
-          eventBuilder_.setMessage(builderForValue.build());
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          policyRuleIdList_ = java.util.Collections.unmodifiableList(policyRuleIdList_);
         }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return policy.Policy.internal_static_policy_PolicyRuleIdList_descriptor;
+    }
 
-        return this;
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return policy.Policy.internal_static_policy_PolicyRuleIdList_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              policy.Policy.PolicyRuleIdList.class, policy.Policy.PolicyRuleIdList.Builder.class);
+    }
+
+    public static final int POLICYRULEIDLIST_FIELD_NUMBER = 1;
+    private java.util.List<policy.Policy.PolicyRuleId> policyRuleIdList_;
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<policy.Policy.PolicyRuleId> getPolicyRuleIdListList() {
+      return policyRuleIdList_;
+    }
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends policy.Policy.PolicyRuleIdOrBuilder> 
+        getPolicyRuleIdListOrBuilderList() {
+      return policyRuleIdList_;
+    }
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    @java.lang.Override
+    public int getPolicyRuleIdListCount() {
+      return policyRuleIdList_.size();
+    }
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    @java.lang.Override
+    public policy.Policy.PolicyRuleId getPolicyRuleIdList(int index) {
+      return policyRuleIdList_.get(index);
+    }
+    /**
+     * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+     */
+    @java.lang.Override
+    public policy.Policy.PolicyRuleIdOrBuilder getPolicyRuleIdListOrBuilder(
+        int index) {
+      return policyRuleIdList_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < policyRuleIdList_.size(); i++) {
+        output.writeMessage(1, policyRuleIdList_.get(i));
       }
-      /**
-       * <pre>
-       * Event-Condition-Action model
-       * </pre>
-       *
-       * <code>.policy.PolicyRuleEvent event = 4;</code>
-       */
-      public Builder mergeEvent(policy.Policy.PolicyRuleEvent value) {
-        if (eventBuilder_ == null) {
-          if (event_ != null) {
-            event_ =
-              policy.Policy.PolicyRuleEvent.newBuilder(event_).mergeFrom(value).buildPartial();
-          } else {
-            event_ = value;
-          }
-          onChanged();
-        } else {
-          eventBuilder_.mergeFrom(value);
-        }
+      unknownFields.writeTo(output);
+    }
 
-        return this;
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < policyRuleIdList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, policyRuleIdList_.get(i));
       }
-      /**
-       * <pre>
-       * Event-Condition-Action model
-       * </pre>
-       *
-       * <code>.policy.PolicyRuleEvent event = 4;</code>
-       */
-      public Builder clearEvent() {
-        if (eventBuilder_ == null) {
-          event_ = null;
-          onChanged();
-        } else {
-          event_ = null;
-          eventBuilder_ = null;
-        }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
 
-        return this;
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
       }
-      /**
-       * <pre>
-       * Event-Condition-Action model
-       * </pre>
-       *
-       * <code>.policy.PolicyRuleEvent event = 4;</code>
-       */
-      public policy.Policy.PolicyRuleEvent.Builder getEventBuilder() {
-        
-        onChanged();
-        return getEventFieldBuilder().getBuilder();
+      if (!(obj instanceof policy.Policy.PolicyRuleIdList)) {
+        return super.equals(obj);
       }
-      /**
-       * <pre>
-       * Event-Condition-Action model
-       * </pre>
-       *
-       * <code>.policy.PolicyRuleEvent event = 4;</code>
-       */
-      public policy.Policy.PolicyRuleEventOrBuilder getEventOrBuilder() {
-        if (eventBuilder_ != null) {
-          return eventBuilder_.getMessageOrBuilder();
-        } else {
-          return event_ == null ?
-              policy.Policy.PolicyRuleEvent.getDefaultInstance() : event_;
-        }
+      policy.Policy.PolicyRuleIdList other = (policy.Policy.PolicyRuleIdList) obj;
+
+      if (!getPolicyRuleIdListList()
+          .equals(other.getPolicyRuleIdListList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
       }
-      /**
-       * <pre>
-       * Event-Condition-Action model
-       * </pre>
-       *
-       * <code>.policy.PolicyRuleEvent event = 4;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          policy.Policy.PolicyRuleEvent, policy.Policy.PolicyRuleEvent.Builder, policy.Policy.PolicyRuleEventOrBuilder> 
-          getEventFieldBuilder() {
-        if (eventBuilder_ == null) {
-          eventBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              policy.Policy.PolicyRuleEvent, policy.Policy.PolicyRuleEvent.Builder, policy.Policy.PolicyRuleEventOrBuilder>(
-                  getEvent(),
-                  getParentForChildren(),
-                  isClean());
-          event_ = null;
-        }
-        return eventBuilder_;
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getPolicyRuleIdListCount() > 0) {
+        hash = (37 * hash) + POLICYRULEIDLIST_FIELD_NUMBER;
+        hash = (53 * hash) + getPolicyRuleIdListList().hashCode();
+      }
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static policy.Policy.PolicyRuleIdList parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.Policy.PolicyRuleIdList parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleIdList parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.Policy.PolicyRuleIdList parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleIdList parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.Policy.PolicyRuleIdList parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleIdList parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.Policy.PolicyRuleIdList parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleIdList parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static policy.Policy.PolicyRuleIdList parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleIdList parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.Policy.PolicyRuleIdList parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(policy.Policy.PolicyRuleIdList prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * A list of policy rule IDs
+     * </pre>
+     *
+     * Protobuf type {@code policy.PolicyRuleIdList}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleIdList)
+        policy.Policy.PolicyRuleIdListOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return policy.Policy.internal_static_policy_PolicyRuleIdList_descriptor;
       }
 
-      private java.util.List<policy.PolicyCondition.PolicyRuleCondition> conditionList_ =
-        java.util.Collections.emptyList();
-      private void ensureConditionListIsMutable() {
-        if (!((bitField0_ & 0x00000001) != 0)) {
-          conditionList_ = new java.util.ArrayList<policy.PolicyCondition.PolicyRuleCondition>(conditionList_);
-          bitField0_ |= 0x00000001;
-         }
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return policy.Policy.internal_static_policy_PolicyRuleIdList_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                policy.Policy.PolicyRuleIdList.class, policy.Policy.PolicyRuleIdList.Builder.class);
       }
 
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.PolicyCondition.PolicyRuleCondition, policy.PolicyCondition.PolicyRuleCondition.Builder, policy.PolicyCondition.PolicyRuleConditionOrBuilder> conditionListBuilder_;
-
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public java.util.List<policy.PolicyCondition.PolicyRuleCondition> getConditionListList() {
-        if (conditionListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(conditionList_);
-        } else {
-          return conditionListBuilder_.getMessageList();
-        }
-      }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public int getConditionListCount() {
-        if (conditionListBuilder_ == null) {
-          return conditionList_.size();
-        } else {
-          return conditionListBuilder_.getCount();
-        }
-      }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public policy.PolicyCondition.PolicyRuleCondition getConditionList(int index) {
-        if (conditionListBuilder_ == null) {
-          return conditionList_.get(index);
-        } else {
-          return conditionListBuilder_.getMessage(index);
-        }
-      }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public Builder setConditionList(
-          int index, policy.PolicyCondition.PolicyRuleCondition value) {
-        if (conditionListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureConditionListIsMutable();
-          conditionList_.set(index, value);
-          onChanged();
-        } else {
-          conditionListBuilder_.setMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public Builder setConditionList(
-          int index, policy.PolicyCondition.PolicyRuleCondition.Builder builderForValue) {
-        if (conditionListBuilder_ == null) {
-          ensureConditionListIsMutable();
-          conditionList_.set(index, builderForValue.build());
-          onChanged();
-        } else {
-          conditionListBuilder_.setMessage(index, builderForValue.build());
-        }
-        return this;
-      }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public Builder addConditionList(policy.PolicyCondition.PolicyRuleCondition value) {
-        if (conditionListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureConditionListIsMutable();
-          conditionList_.add(value);
-          onChanged();
-        } else {
-          conditionListBuilder_.addMessage(value);
-        }
-        return this;
-      }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public Builder addConditionList(
-          int index, policy.PolicyCondition.PolicyRuleCondition value) {
-        if (conditionListBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          ensureConditionListIsMutable();
-          conditionList_.add(index, value);
-          onChanged();
-        } else {
-          conditionListBuilder_.addMessage(index, value);
-        }
-        return this;
-      }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public Builder addConditionList(
-          policy.PolicyCondition.PolicyRuleCondition.Builder builderForValue) {
-        if (conditionListBuilder_ == null) {
-          ensureConditionListIsMutable();
-          conditionList_.add(builderForValue.build());
-          onChanged();
-        } else {
-          conditionListBuilder_.addMessage(builderForValue.build());
-        }
-        return this;
+      // Construct using policy.Policy.PolicyRuleIdList.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public Builder addConditionList(
-          int index, policy.PolicyCondition.PolicyRuleCondition.Builder builderForValue) {
-        if (conditionListBuilder_ == null) {
-          ensureConditionListIsMutable();
-          conditionList_.add(index, builderForValue.build());
-          onChanged();
-        } else {
-          conditionListBuilder_.addMessage(index, builderForValue.build());
-        }
-        return this;
+
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public Builder addAllConditionList(
-          java.lang.Iterable<? extends policy.PolicyCondition.PolicyRuleCondition> values) {
-        if (conditionListBuilder_ == null) {
-          ensureConditionListIsMutable();
-          com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, conditionList_);
-          onChanged();
-        } else {
-          conditionListBuilder_.addAllMessages(values);
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getPolicyRuleIdListFieldBuilder();
         }
-        return this;
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public Builder clearConditionList() {
-        if (conditionListBuilder_ == null) {
-          conditionList_ = java.util.Collections.emptyList();
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (policyRuleIdListBuilder_ == null) {
+          policyRuleIdList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
-          onChanged();
         } else {
-          conditionListBuilder_.clear();
+          policyRuleIdListBuilder_.clear();
         }
         return this;
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public Builder removeConditionList(int index) {
-        if (conditionListBuilder_ == null) {
-          ensureConditionListIsMutable();
-          conditionList_.remove(index);
-          onChanged();
-        } else {
-          conditionListBuilder_.remove(index);
-        }
-        return this;
+
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return policy.Policy.internal_static_policy_PolicyRuleIdList_descriptor;
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public policy.PolicyCondition.PolicyRuleCondition.Builder getConditionListBuilder(
-          int index) {
-        return getConditionListFieldBuilder().getBuilder(index);
+
+      @java.lang.Override
+      public policy.Policy.PolicyRuleIdList getDefaultInstanceForType() {
+        return policy.Policy.PolicyRuleIdList.getDefaultInstance();
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public policy.PolicyCondition.PolicyRuleConditionOrBuilder getConditionListOrBuilder(
-          int index) {
-        if (conditionListBuilder_ == null) {
-          return conditionList_.get(index);  } else {
-          return conditionListBuilder_.getMessageOrBuilder(index);
+
+      @java.lang.Override
+      public policy.Policy.PolicyRuleIdList build() {
+        policy.Policy.PolicyRuleIdList result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
         }
+        return result;
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public java.util.List<? extends policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
-           getConditionListOrBuilderList() {
-        if (conditionListBuilder_ != null) {
-          return conditionListBuilder_.getMessageOrBuilderList();
+
+      @java.lang.Override
+      public policy.Policy.PolicyRuleIdList buildPartial() {
+        policy.Policy.PolicyRuleIdList result = new policy.Policy.PolicyRuleIdList(this);
+        int from_bitField0_ = bitField0_;
+        if (policyRuleIdListBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            policyRuleIdList_ = java.util.Collections.unmodifiableList(policyRuleIdList_);
+            bitField0_ = (bitField0_ & ~0x00000001);
+          }
+          result.policyRuleIdList_ = policyRuleIdList_;
         } else {
-          return java.util.Collections.unmodifiableList(conditionList_);
+          result.policyRuleIdList_ = policyRuleIdListBuilder_.build();
         }
+        onBuilt();
+        return result;
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public policy.PolicyCondition.PolicyRuleCondition.Builder addConditionListBuilder() {
-        return getConditionListFieldBuilder().addBuilder(
-            policy.PolicyCondition.PolicyRuleCondition.getDefaultInstance());
+
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public policy.PolicyCondition.PolicyRuleCondition.Builder addConditionListBuilder(
-          int index) {
-        return getConditionListFieldBuilder().addBuilder(
-            index, policy.PolicyCondition.PolicyRuleCondition.getDefaultInstance());
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
       }
-      /**
-       * <pre>
-       * One or more conditions must be met
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleCondition conditionList = 5;</code>
-       */
-      public java.util.List<policy.PolicyCondition.PolicyRuleCondition.Builder> 
-           getConditionListBuilderList() {
-        return getConditionListFieldBuilder().getBuilderList();
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
       }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.PolicyCondition.PolicyRuleCondition, policy.PolicyCondition.PolicyRuleCondition.Builder, policy.PolicyCondition.PolicyRuleConditionOrBuilder> 
-          getConditionListFieldBuilder() {
-        if (conditionListBuilder_ == null) {
-          conditionListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              policy.PolicyCondition.PolicyRuleCondition, policy.PolicyCondition.PolicyRuleCondition.Builder, policy.PolicyCondition.PolicyRuleConditionOrBuilder>(
-                  conditionList_,
-                  ((bitField0_ & 0x00000001) != 0),
-                  getParentForChildren(),
-                  isClean());
-          conditionList_ = null;
-        }
-        return conditionListBuilder_;
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
       }
-
-      private int booleanOperator_ = 0;
-      /**
-       * <pre>
-       * Evaluation operator to be used
-       * </pre>
-       *
-       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
-       * @return The enum numeric value on the wire for booleanOperator.
-       */
-      @java.lang.Override public int getBooleanOperatorValue() {
-        return booleanOperator_;
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
       }
-      /**
-       * <pre>
-       * Evaluation operator to be used
-       * </pre>
-       *
-       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
-       * @param value The enum numeric value on the wire for booleanOperator to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBooleanOperatorValue(int value) {
-        
-        booleanOperator_ = value;
-        onChanged();
-        return this;
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
       }
-      /**
-       * <pre>
-       * Evaluation operator to be used
-       * </pre>
-       *
-       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
-       * @return The booleanOperator.
-       */
       @java.lang.Override
-      public policy.PolicyCondition.BooleanOperator getBooleanOperator() {
-        @SuppressWarnings("deprecation")
-        policy.PolicyCondition.BooleanOperator result = policy.PolicyCondition.BooleanOperator.valueOf(booleanOperator_);
-        return result == null ? policy.PolicyCondition.BooleanOperator.UNRECOGNIZED : result;
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof policy.Policy.PolicyRuleIdList) {
+          return mergeFrom((policy.Policy.PolicyRuleIdList)other);
+        } else {
+          super.mergeFrom(other);
+          return this;
+        }
       }
-      /**
-       * <pre>
-       * Evaluation operator to be used
-       * </pre>
-       *
-       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
-       * @param value The booleanOperator to set.
-       * @return This builder for chaining.
-       */
-      public Builder setBooleanOperator(policy.PolicyCondition.BooleanOperator value) {
-        if (value == null) {
-          throw new NullPointerException();
+
+      public Builder mergeFrom(policy.Policy.PolicyRuleIdList other) {
+        if (other == policy.Policy.PolicyRuleIdList.getDefaultInstance()) return this;
+        if (policyRuleIdListBuilder_ == null) {
+          if (!other.policyRuleIdList_.isEmpty()) {
+            if (policyRuleIdList_.isEmpty()) {
+              policyRuleIdList_ = other.policyRuleIdList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensurePolicyRuleIdListIsMutable();
+              policyRuleIdList_.addAll(other.policyRuleIdList_);
+            }
+            onChanged();
+          }
+        } else {
+          if (!other.policyRuleIdList_.isEmpty()) {
+            if (policyRuleIdListBuilder_.isEmpty()) {
+              policyRuleIdListBuilder_.dispose();
+              policyRuleIdListBuilder_ = null;
+              policyRuleIdList_ = other.policyRuleIdList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              policyRuleIdListBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getPolicyRuleIdListFieldBuilder() : null;
+            } else {
+              policyRuleIdListBuilder_.addAllMessages(other.policyRuleIdList_);
+            }
+          }
         }
-        
-        booleanOperator_ = value.getNumber();
+        this.mergeUnknownFields(other.unknownFields);
         onChanged();
         return this;
       }
-      /**
-       * <pre>
-       * Evaluation operator to be used
-       * </pre>
-       *
-       * <code>.policy.BooleanOperator booleanOperator = 6;</code>
-       * @return This builder for chaining.
-       */
-      public Builder clearBooleanOperator() {
-        
-        booleanOperator_ = 0;
-        onChanged();
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        policy.Policy.PolicyRuleIdList parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (policy.Policy.PolicyRuleIdList) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
+        }
         return this;
       }
+      private int bitField0_;
 
-      private java.util.List<policy.PolicyAction.PolicyRuleAction> actionList_ =
+      private java.util.List<policy.Policy.PolicyRuleId> policyRuleIdList_ =
         java.util.Collections.emptyList();
-      private void ensureActionListIsMutable() {
-        if (!((bitField0_ & 0x00000002) != 0)) {
-          actionList_ = new java.util.ArrayList<policy.PolicyAction.PolicyRuleAction>(actionList_);
-          bitField0_ |= 0x00000002;
+      private void ensurePolicyRuleIdListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          policyRuleIdList_ = new java.util.ArrayList<policy.Policy.PolicyRuleId>(policyRuleIdList_);
+          bitField0_ |= 0x00000001;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.PolicyAction.PolicyRuleAction, policy.PolicyAction.PolicyRuleAction.Builder, policy.PolicyAction.PolicyRuleActionOrBuilder> actionListBuilder_;
+          policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleId.Builder, policy.Policy.PolicyRuleIdOrBuilder> policyRuleIdListBuilder_;
 
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public java.util.List<policy.PolicyAction.PolicyRuleAction> getActionListList() {
-        if (actionListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(actionList_);
+      public java.util.List<policy.Policy.PolicyRuleId> getPolicyRuleIdListList() {
+        if (policyRuleIdListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(policyRuleIdList_);
         } else {
-          return actionListBuilder_.getMessageList();
+          return policyRuleIdListBuilder_.getMessageList();
         }
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public int getActionListCount() {
-        if (actionListBuilder_ == null) {
-          return actionList_.size();
+      public int getPolicyRuleIdListCount() {
+        if (policyRuleIdListBuilder_ == null) {
+          return policyRuleIdList_.size();
         } else {
-          return actionListBuilder_.getCount();
+          return policyRuleIdListBuilder_.getCount();
         }
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public policy.PolicyAction.PolicyRuleAction getActionList(int index) {
-        if (actionListBuilder_ == null) {
-          return actionList_.get(index);
+      public policy.Policy.PolicyRuleId getPolicyRuleIdList(int index) {
+        if (policyRuleIdListBuilder_ == null) {
+          return policyRuleIdList_.get(index);
         } else {
-          return actionListBuilder_.getMessage(index);
+          return policyRuleIdListBuilder_.getMessage(index);
         }
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public Builder setActionList(
-          int index, policy.PolicyAction.PolicyRuleAction value) {
-        if (actionListBuilder_ == null) {
+      public Builder setPolicyRuleIdList(
+          int index, policy.Policy.PolicyRuleId value) {
+        if (policyRuleIdListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureActionListIsMutable();
-          actionList_.set(index, value);
+          ensurePolicyRuleIdListIsMutable();
+          policyRuleIdList_.set(index, value);
           onChanged();
         } else {
-          actionListBuilder_.setMessage(index, value);
+          policyRuleIdListBuilder_.setMessage(index, value);
         }
         return this;
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public Builder setActionList(
-          int index, policy.PolicyAction.PolicyRuleAction.Builder builderForValue) {
-        if (actionListBuilder_ == null) {
-          ensureActionListIsMutable();
-          actionList_.set(index, builderForValue.build());
+      public Builder setPolicyRuleIdList(
+          int index, policy.Policy.PolicyRuleId.Builder builderForValue) {
+        if (policyRuleIdListBuilder_ == null) {
+          ensurePolicyRuleIdListIsMutable();
+          policyRuleIdList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          actionListBuilder_.setMessage(index, builderForValue.build());
+          policyRuleIdListBuilder_.setMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public Builder addActionList(policy.PolicyAction.PolicyRuleAction value) {
-        if (actionListBuilder_ == null) {
+      public Builder addPolicyRuleIdList(policy.Policy.PolicyRuleId value) {
+        if (policyRuleIdListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureActionListIsMutable();
-          actionList_.add(value);
+          ensurePolicyRuleIdListIsMutable();
+          policyRuleIdList_.add(value);
           onChanged();
         } else {
-          actionListBuilder_.addMessage(value);
+          policyRuleIdListBuilder_.addMessage(value);
         }
         return this;
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public Builder addActionList(
-          int index, policy.PolicyAction.PolicyRuleAction value) {
-        if (actionListBuilder_ == null) {
+      public Builder addPolicyRuleIdList(
+          int index, policy.Policy.PolicyRuleId value) {
+        if (policyRuleIdListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureActionListIsMutable();
-          actionList_.add(index, value);
+          ensurePolicyRuleIdListIsMutable();
+          policyRuleIdList_.add(index, value);
           onChanged();
         } else {
-          actionListBuilder_.addMessage(index, value);
+          policyRuleIdListBuilder_.addMessage(index, value);
         }
         return this;
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public Builder addActionList(
-          policy.PolicyAction.PolicyRuleAction.Builder builderForValue) {
-        if (actionListBuilder_ == null) {
-          ensureActionListIsMutable();
-          actionList_.add(builderForValue.build());
+      public Builder addPolicyRuleIdList(
+          policy.Policy.PolicyRuleId.Builder builderForValue) {
+        if (policyRuleIdListBuilder_ == null) {
+          ensurePolicyRuleIdListIsMutable();
+          policyRuleIdList_.add(builderForValue.build());
           onChanged();
         } else {
-          actionListBuilder_.addMessage(builderForValue.build());
+          policyRuleIdListBuilder_.addMessage(builderForValue.build());
         }
         return this;
-      }
-      /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+      }
+      /**
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public Builder addActionList(
-          int index, policy.PolicyAction.PolicyRuleAction.Builder builderForValue) {
-        if (actionListBuilder_ == null) {
-          ensureActionListIsMutable();
-          actionList_.add(index, builderForValue.build());
+      public Builder addPolicyRuleIdList(
+          int index, policy.Policy.PolicyRuleId.Builder builderForValue) {
+        if (policyRuleIdListBuilder_ == null) {
+          ensurePolicyRuleIdListIsMutable();
+          policyRuleIdList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          actionListBuilder_.addMessage(index, builderForValue.build());
+          policyRuleIdListBuilder_.addMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public Builder addAllActionList(
-          java.lang.Iterable<? extends policy.PolicyAction.PolicyRuleAction> values) {
-        if (actionListBuilder_ == null) {
-          ensureActionListIsMutable();
+      public Builder addAllPolicyRuleIdList(
+          java.lang.Iterable<? extends policy.Policy.PolicyRuleId> values) {
+        if (policyRuleIdListBuilder_ == null) {
+          ensurePolicyRuleIdListIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, actionList_);
+              values, policyRuleIdList_);
           onChanged();
         } else {
-          actionListBuilder_.addAllMessages(values);
+          policyRuleIdListBuilder_.addAllMessages(values);
         }
         return this;
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public Builder clearActionList() {
-        if (actionListBuilder_ == null) {
-          actionList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000002);
+      public Builder clearPolicyRuleIdList() {
+        if (policyRuleIdListBuilder_ == null) {
+          policyRuleIdList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          actionListBuilder_.clear();
+          policyRuleIdListBuilder_.clear();
         }
         return this;
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public Builder removeActionList(int index) {
-        if (actionListBuilder_ == null) {
-          ensureActionListIsMutable();
-          actionList_.remove(index);
+      public Builder removePolicyRuleIdList(int index) {
+        if (policyRuleIdListBuilder_ == null) {
+          ensurePolicyRuleIdListIsMutable();
+          policyRuleIdList_.remove(index);
           onChanged();
         } else {
-          actionListBuilder_.remove(index);
+          policyRuleIdListBuilder_.remove(index);
         }
         return this;
       }
       /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
        */
-      public policy.PolicyAction.PolicyRuleAction.Builder getActionListBuilder(
+      public policy.Policy.PolicyRuleId.Builder getPolicyRuleIdListBuilder(
           int index) {
-        return getActionListFieldBuilder().getBuilder(index);
+        return getPolicyRuleIdListFieldBuilder().getBuilder(index);
+      }
+      /**
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+       */
+      public policy.Policy.PolicyRuleIdOrBuilder getPolicyRuleIdListOrBuilder(
+          int index) {
+        if (policyRuleIdListBuilder_ == null) {
+          return policyRuleIdList_.get(index);  } else {
+          return policyRuleIdListBuilder_.getMessageOrBuilder(index);
+        }
+      }
+      /**
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+       */
+      public java.util.List<? extends policy.Policy.PolicyRuleIdOrBuilder> 
+           getPolicyRuleIdListOrBuilderList() {
+        if (policyRuleIdListBuilder_ != null) {
+          return policyRuleIdListBuilder_.getMessageOrBuilderList();
+        } else {
+          return java.util.Collections.unmodifiableList(policyRuleIdList_);
+        }
+      }
+      /**
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+       */
+      public policy.Policy.PolicyRuleId.Builder addPolicyRuleIdListBuilder() {
+        return getPolicyRuleIdListFieldBuilder().addBuilder(
+            policy.Policy.PolicyRuleId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+       */
+      public policy.Policy.PolicyRuleId.Builder addPolicyRuleIdListBuilder(
+          int index) {
+        return getPolicyRuleIdListFieldBuilder().addBuilder(
+            index, policy.Policy.PolicyRuleId.getDefaultInstance());
+      }
+      /**
+       * <code>repeated .policy.PolicyRuleId policyRuleIdList = 1;</code>
+       */
+      public java.util.List<policy.Policy.PolicyRuleId.Builder> 
+           getPolicyRuleIdListBuilderList() {
+        return getPolicyRuleIdListFieldBuilder().getBuilderList();
+      }
+      private com.google.protobuf.RepeatedFieldBuilderV3<
+          policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleId.Builder, policy.Policy.PolicyRuleIdOrBuilder> 
+          getPolicyRuleIdListFieldBuilder() {
+        if (policyRuleIdListBuilder_ == null) {
+          policyRuleIdListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleId.Builder, policy.Policy.PolicyRuleIdOrBuilder>(
+                  policyRuleIdList_,
+                  ((bitField0_ & 0x00000001) != 0),
+                  getParentForChildren(),
+                  isClean());
+          policyRuleIdList_ = null;
+        }
+        return policyRuleIdListBuilder_;
+      }
+      @java.lang.Override
+      public final Builder setUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.setUnknownFields(unknownFields);
+      }
+
+      @java.lang.Override
+      public final Builder mergeUnknownFields(
+          final com.google.protobuf.UnknownFieldSet unknownFields) {
+        return super.mergeUnknownFields(unknownFields);
+      }
+
+
+      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleIdList)
+    }
+
+    // @@protoc_insertion_point(class_scope:policy.PolicyRuleIdList)
+    private static final policy.Policy.PolicyRuleIdList DEFAULT_INSTANCE;
+    static {
+      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleIdList();
+    }
+
+    public static policy.Policy.PolicyRuleIdList getDefaultInstance() {
+      return DEFAULT_INSTANCE;
+    }
+
+    private static final com.google.protobuf.Parser<PolicyRuleIdList>
+        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleIdList>() {
+      @java.lang.Override
+      public PolicyRuleIdList parsePartialFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws com.google.protobuf.InvalidProtocolBufferException {
+        return new PolicyRuleIdList(input, extensionRegistry);
+      }
+    };
+
+    public static com.google.protobuf.Parser<PolicyRuleIdList> parser() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public com.google.protobuf.Parser<PolicyRuleIdList> getParserForType() {
+      return PARSER;
+    }
+
+    @java.lang.Override
+    public policy.Policy.PolicyRuleIdList getDefaultInstanceForType() {
+      return DEFAULT_INSTANCE;
+    }
+
+  }
+
+  public interface PolicyRuleServiceListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleServiceList)
+      com.google.protobuf.MessageOrBuilder {
+
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    java.util.List<policy.Policy.PolicyRuleService> 
+        getPolicyRuleServiceListList();
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    policy.Policy.PolicyRuleService getPolicyRuleServiceList(int index);
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    int getPolicyRuleServiceListCount();
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    java.util.List<? extends policy.Policy.PolicyRuleServiceOrBuilder> 
+        getPolicyRuleServiceListOrBuilderList();
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    policy.Policy.PolicyRuleServiceOrBuilder getPolicyRuleServiceListOrBuilder(
+        int index);
+  }
+  /**
+   * <pre>
+   * A list of service-oriented policy rules
+   * </pre>
+   *
+   * Protobuf type {@code policy.PolicyRuleServiceList}
+   */
+  public static final class PolicyRuleServiceList extends
+      com.google.protobuf.GeneratedMessageV3 implements
+      // @@protoc_insertion_point(message_implements:policy.PolicyRuleServiceList)
+      PolicyRuleServiceListOrBuilder {
+  private static final long serialVersionUID = 0L;
+    // Use PolicyRuleServiceList.newBuilder() to construct.
+    private PolicyRuleServiceList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+      super(builder);
+    }
+    private PolicyRuleServiceList() {
+      policyRuleServiceList_ = java.util.Collections.emptyList();
+    }
+
+    @java.lang.Override
+    @SuppressWarnings({"unused"})
+    protected java.lang.Object newInstance(
+        UnusedPrivateParameter unused) {
+      return new PolicyRuleServiceList();
+    }
+
+    @java.lang.Override
+    public final com.google.protobuf.UnknownFieldSet
+    getUnknownFields() {
+      return this.unknownFields;
+    }
+    private PolicyRuleServiceList(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      this();
+      if (extensionRegistry == null) {
+        throw new java.lang.NullPointerException();
+      }
+      int mutable_bitField0_ = 0;
+      com.google.protobuf.UnknownFieldSet.Builder unknownFields =
+          com.google.protobuf.UnknownFieldSet.newBuilder();
+      try {
+        boolean done = false;
+        while (!done) {
+          int tag = input.readTag();
+          switch (tag) {
+            case 0:
+              done = true;
+              break;
+            case 10: {
+              if (!((mutable_bitField0_ & 0x00000001) != 0)) {
+                policyRuleServiceList_ = new java.util.ArrayList<policy.Policy.PolicyRuleService>();
+                mutable_bitField0_ |= 0x00000001;
+              }
+              policyRuleServiceList_.add(
+                  input.readMessage(policy.Policy.PolicyRuleService.parser(), extensionRegistry));
+              break;
+            }
+            default: {
+              if (!parseUnknownField(
+                  input, unknownFields, extensionRegistry, tag)) {
+                done = true;
+              }
+              break;
+            }
+          }
+        }
+      } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+        throw e.setUnfinishedMessage(this);
+      } catch (java.io.IOException e) {
+        throw new com.google.protobuf.InvalidProtocolBufferException(
+            e).setUnfinishedMessage(this);
+      } finally {
+        if (((mutable_bitField0_ & 0x00000001) != 0)) {
+          policyRuleServiceList_ = java.util.Collections.unmodifiableList(policyRuleServiceList_);
+        }
+        this.unknownFields = unknownFields.build();
+        makeExtensionsImmutable();
+      }
+    }
+    public static final com.google.protobuf.Descriptors.Descriptor
+        getDescriptor() {
+      return policy.Policy.internal_static_policy_PolicyRuleServiceList_descriptor;
+    }
+
+    @java.lang.Override
+    protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+        internalGetFieldAccessorTable() {
+      return policy.Policy.internal_static_policy_PolicyRuleServiceList_fieldAccessorTable
+          .ensureFieldAccessorsInitialized(
+              policy.Policy.PolicyRuleServiceList.class, policy.Policy.PolicyRuleServiceList.Builder.class);
+    }
+
+    public static final int POLICYRULESERVICELIST_FIELD_NUMBER = 1;
+    private java.util.List<policy.Policy.PolicyRuleService> policyRuleServiceList_;
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<policy.Policy.PolicyRuleService> getPolicyRuleServiceListList() {
+      return policyRuleServiceList_;
+    }
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    @java.lang.Override
+    public java.util.List<? extends policy.Policy.PolicyRuleServiceOrBuilder> 
+        getPolicyRuleServiceListOrBuilderList() {
+      return policyRuleServiceList_;
+    }
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    @java.lang.Override
+    public int getPolicyRuleServiceListCount() {
+      return policyRuleServiceList_.size();
+    }
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    @java.lang.Override
+    public policy.Policy.PolicyRuleService getPolicyRuleServiceList(int index) {
+      return policyRuleServiceList_.get(index);
+    }
+    /**
+     * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
+     */
+    @java.lang.Override
+    public policy.Policy.PolicyRuleServiceOrBuilder getPolicyRuleServiceListOrBuilder(
+        int index) {
+      return policyRuleServiceList_.get(index);
+    }
+
+    private byte memoizedIsInitialized = -1;
+    @java.lang.Override
+    public final boolean isInitialized() {
+      byte isInitialized = memoizedIsInitialized;
+      if (isInitialized == 1) return true;
+      if (isInitialized == 0) return false;
+
+      memoizedIsInitialized = 1;
+      return true;
+    }
+
+    @java.lang.Override
+    public void writeTo(com.google.protobuf.CodedOutputStream output)
+                        throws java.io.IOException {
+      for (int i = 0; i < policyRuleServiceList_.size(); i++) {
+        output.writeMessage(1, policyRuleServiceList_.get(i));
+      }
+      unknownFields.writeTo(output);
+    }
+
+    @java.lang.Override
+    public int getSerializedSize() {
+      int size = memoizedSize;
+      if (size != -1) return size;
+
+      size = 0;
+      for (int i = 0; i < policyRuleServiceList_.size(); i++) {
+        size += com.google.protobuf.CodedOutputStream
+          .computeMessageSize(1, policyRuleServiceList_.get(i));
+      }
+      size += unknownFields.getSerializedSize();
+      memoizedSize = size;
+      return size;
+    }
+
+    @java.lang.Override
+    public boolean equals(final java.lang.Object obj) {
+      if (obj == this) {
+       return true;
       }
-      /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-       */
-      public policy.PolicyAction.PolicyRuleActionOrBuilder getActionListOrBuilder(
-          int index) {
-        if (actionListBuilder_ == null) {
-          return actionList_.get(index);  } else {
-          return actionListBuilder_.getMessageOrBuilder(index);
-        }
+      if (!(obj instanceof policy.Policy.PolicyRuleServiceList)) {
+        return super.equals(obj);
       }
-      /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-       */
-      public java.util.List<? extends policy.PolicyAction.PolicyRuleActionOrBuilder> 
-           getActionListOrBuilderList() {
-        if (actionListBuilder_ != null) {
-          return actionListBuilder_.getMessageOrBuilderList();
-        } else {
-          return java.util.Collections.unmodifiableList(actionList_);
-        }
+      policy.Policy.PolicyRuleServiceList other = (policy.Policy.PolicyRuleServiceList) obj;
+
+      if (!getPolicyRuleServiceListList()
+          .equals(other.getPolicyRuleServiceListList())) return false;
+      if (!unknownFields.equals(other.unknownFields)) return false;
+      return true;
+    }
+
+    @java.lang.Override
+    public int hashCode() {
+      if (memoizedHashCode != 0) {
+        return memoizedHashCode;
       }
-      /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-       */
-      public policy.PolicyAction.PolicyRuleAction.Builder addActionListBuilder() {
-        return getActionListFieldBuilder().addBuilder(
-            policy.PolicyAction.PolicyRuleAction.getDefaultInstance());
+      int hash = 41;
+      hash = (19 * hash) + getDescriptor().hashCode();
+      if (getPolicyRuleServiceListCount() > 0) {
+        hash = (37 * hash) + POLICYRULESERVICELIST_FIELD_NUMBER;
+        hash = (53 * hash) + getPolicyRuleServiceListList().hashCode();
       }
-      /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-       */
-      public policy.PolicyAction.PolicyRuleAction.Builder addActionListBuilder(
-          int index) {
-        return getActionListFieldBuilder().addBuilder(
-            index, policy.PolicyAction.PolicyRuleAction.getDefaultInstance());
+      hash = (29 * hash) + unknownFields.hashCode();
+      memoizedHashCode = hash;
+      return hash;
+    }
+
+    public static policy.Policy.PolicyRuleServiceList parseFrom(
+        java.nio.ByteBuffer data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseFrom(
+        java.nio.ByteBuffer data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseFrom(
+        com.google.protobuf.ByteString data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseFrom(
+        com.google.protobuf.ByteString data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseFrom(byte[] data)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseFrom(
+        byte[] data,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws com.google.protobuf.InvalidProtocolBufferException {
+      return PARSER.parseFrom(data, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseDelimitedFrom(java.io.InputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseDelimitedFrom(
+        java.io.InputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseFrom(
+        com.google.protobuf.CodedInputStream input)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input);
+    }
+    public static policy.Policy.PolicyRuleServiceList parseFrom(
+        com.google.protobuf.CodedInputStream input,
+        com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+        throws java.io.IOException {
+      return com.google.protobuf.GeneratedMessageV3
+          .parseWithIOException(PARSER, input, extensionRegistry);
+    }
+
+    @java.lang.Override
+    public Builder newBuilderForType() { return newBuilder(); }
+    public static Builder newBuilder() {
+      return DEFAULT_INSTANCE.toBuilder();
+    }
+    public static Builder newBuilder(policy.Policy.PolicyRuleServiceList prototype) {
+      return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
+    }
+    @java.lang.Override
+    public Builder toBuilder() {
+      return this == DEFAULT_INSTANCE
+          ? new Builder() : new Builder().mergeFrom(this);
+    }
+
+    @java.lang.Override
+    protected Builder newBuilderForType(
+        com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+      Builder builder = new Builder(parent);
+      return builder;
+    }
+    /**
+     * <pre>
+     * A list of service-oriented policy rules
+     * </pre>
+     *
+     * Protobuf type {@code policy.PolicyRuleServiceList}
+     */
+    public static final class Builder extends
+        com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
+        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleServiceList)
+        policy.Policy.PolicyRuleServiceListOrBuilder {
+      public static final com.google.protobuf.Descriptors.Descriptor
+          getDescriptor() {
+        return policy.Policy.internal_static_policy_PolicyRuleServiceList_descriptor;
       }
-      /**
-       * <pre>
-       * One or more actions should be applied
-       * </pre>
-       *
-       * <code>repeated .policy.PolicyRuleAction actionList = 7;</code>
-       */
-      public java.util.List<policy.PolicyAction.PolicyRuleAction.Builder> 
-           getActionListBuilderList() {
-        return getActionListFieldBuilder().getBuilderList();
+
+      @java.lang.Override
+      protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+          internalGetFieldAccessorTable() {
+        return policy.Policy.internal_static_policy_PolicyRuleServiceList_fieldAccessorTable
+            .ensureFieldAccessorsInitialized(
+                policy.Policy.PolicyRuleServiceList.class, policy.Policy.PolicyRuleServiceList.Builder.class);
       }
-      private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.PolicyAction.PolicyRuleAction, policy.PolicyAction.PolicyRuleAction.Builder, policy.PolicyAction.PolicyRuleActionOrBuilder> 
-          getActionListFieldBuilder() {
-        if (actionListBuilder_ == null) {
-          actionListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              policy.PolicyAction.PolicyRuleAction, policy.PolicyAction.PolicyRuleAction.Builder, policy.PolicyAction.PolicyRuleActionOrBuilder>(
-                  actionList_,
-                  ((bitField0_ & 0x00000002) != 0),
-                  getParentForChildren(),
-                  isClean());
-          actionList_ = null;
-        }
-        return actionListBuilder_;
+
+      // Construct using policy.Policy.PolicyRuleServiceList.newBuilder()
+      private Builder() {
+        maybeForceBuilderInitialization();
       }
 
-      private context.ContextOuterClass.ServiceId serviceId_;
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> serviceIdBuilder_;
-      /**
-       * <pre>
-       * Affected service and devices
-       * </pre>
-       *
-       * <code>.context.ServiceId serviceId = 8;</code>
-       * @return Whether the serviceId field is set.
-       */
-      public boolean hasServiceId() {
-        return serviceIdBuilder_ != null || serviceId_ != null;
+      private Builder(
+          com.google.protobuf.GeneratedMessageV3.BuilderParent parent) {
+        super(parent);
+        maybeForceBuilderInitialization();
       }
-      /**
-       * <pre>
-       * Affected service and devices
-       * </pre>
-       *
-       * <code>.context.ServiceId serviceId = 8;</code>
-       * @return The serviceId.
-       */
-      public context.ContextOuterClass.ServiceId getServiceId() {
-        if (serviceIdBuilder_ == null) {
-          return serviceId_ == null ? context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
-        } else {
-          return serviceIdBuilder_.getMessage();
+      private void maybeForceBuilderInitialization() {
+        if (com.google.protobuf.GeneratedMessageV3
+                .alwaysUseFieldBuilders) {
+          getPolicyRuleServiceListFieldBuilder();
         }
       }
-      /**
-       * <pre>
-       * Affected service and devices
-       * </pre>
-       *
-       * <code>.context.ServiceId serviceId = 8;</code>
-       */
-      public Builder setServiceId(context.ContextOuterClass.ServiceId value) {
-        if (serviceIdBuilder_ == null) {
-          if (value == null) {
-            throw new NullPointerException();
-          }
-          serviceId_ = value;
-          onChanged();
+      @java.lang.Override
+      public Builder clear() {
+        super.clear();
+        if (policyRuleServiceListBuilder_ == null) {
+          policyRuleServiceList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
         } else {
-          serviceIdBuilder_.setMessage(value);
+          policyRuleServiceListBuilder_.clear();
         }
-
         return this;
       }
-      /**
-       * <pre>
-       * Affected service and devices
-       * </pre>
-       *
-       * <code>.context.ServiceId serviceId = 8;</code>
-       */
-      public Builder setServiceId(
-          context.ContextOuterClass.ServiceId.Builder builderForValue) {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = builderForValue.build();
-          onChanged();
-        } else {
-          serviceIdBuilder_.setMessage(builderForValue.build());
-        }
 
-        return this;
+      @java.lang.Override
+      public com.google.protobuf.Descriptors.Descriptor
+          getDescriptorForType() {
+        return policy.Policy.internal_static_policy_PolicyRuleServiceList_descriptor;
+      }
+
+      @java.lang.Override
+      public policy.Policy.PolicyRuleServiceList getDefaultInstanceForType() {
+        return policy.Policy.PolicyRuleServiceList.getDefaultInstance();
+      }
+
+      @java.lang.Override
+      public policy.Policy.PolicyRuleServiceList build() {
+        policy.Policy.PolicyRuleServiceList result = buildPartial();
+        if (!result.isInitialized()) {
+          throw newUninitializedMessageException(result);
+        }
+        return result;
       }
-      /**
-       * <pre>
-       * Affected service and devices
-       * </pre>
-       *
-       * <code>.context.ServiceId serviceId = 8;</code>
-       */
-      public Builder mergeServiceId(context.ContextOuterClass.ServiceId value) {
-        if (serviceIdBuilder_ == null) {
-          if (serviceId_ != null) {
-            serviceId_ =
-              context.ContextOuterClass.ServiceId.newBuilder(serviceId_).mergeFrom(value).buildPartial();
-          } else {
-            serviceId_ = value;
+
+      @java.lang.Override
+      public policy.Policy.PolicyRuleServiceList buildPartial() {
+        policy.Policy.PolicyRuleServiceList result = new policy.Policy.PolicyRuleServiceList(this);
+        int from_bitField0_ = bitField0_;
+        if (policyRuleServiceListBuilder_ == null) {
+          if (((bitField0_ & 0x00000001) != 0)) {
+            policyRuleServiceList_ = java.util.Collections.unmodifiableList(policyRuleServiceList_);
+            bitField0_ = (bitField0_ & ~0x00000001);
           }
-          onChanged();
+          result.policyRuleServiceList_ = policyRuleServiceList_;
         } else {
-          serviceIdBuilder_.mergeFrom(value);
+          result.policyRuleServiceList_ = policyRuleServiceListBuilder_.build();
         }
+        onBuilt();
+        return result;
+      }
 
-        return this;
+      @java.lang.Override
+      public Builder clone() {
+        return super.clone();
       }
-      /**
-       * <pre>
-       * Affected service and devices
-       * </pre>
-       *
-       * <code>.context.ServiceId serviceId = 8;</code>
-       */
-      public Builder clearServiceId() {
-        if (serviceIdBuilder_ == null) {
-          serviceId_ = null;
-          onChanged();
+      @java.lang.Override
+      public Builder setField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.setField(field, value);
+      }
+      @java.lang.Override
+      public Builder clearField(
+          com.google.protobuf.Descriptors.FieldDescriptor field) {
+        return super.clearField(field);
+      }
+      @java.lang.Override
+      public Builder clearOneof(
+          com.google.protobuf.Descriptors.OneofDescriptor oneof) {
+        return super.clearOneof(oneof);
+      }
+      @java.lang.Override
+      public Builder setRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          int index, java.lang.Object value) {
+        return super.setRepeatedField(field, index, value);
+      }
+      @java.lang.Override
+      public Builder addRepeatedField(
+          com.google.protobuf.Descriptors.FieldDescriptor field,
+          java.lang.Object value) {
+        return super.addRepeatedField(field, value);
+      }
+      @java.lang.Override
+      public Builder mergeFrom(com.google.protobuf.Message other) {
+        if (other instanceof policy.Policy.PolicyRuleServiceList) {
+          return mergeFrom((policy.Policy.PolicyRuleServiceList)other);
         } else {
-          serviceId_ = null;
-          serviceIdBuilder_ = null;
+          super.mergeFrom(other);
+          return this;
         }
-
-        return this;
-      }
-      /**
-       * <pre>
-       * Affected service and devices
-       * </pre>
-       *
-       * <code>.context.ServiceId serviceId = 8;</code>
-       */
-      public context.ContextOuterClass.ServiceId.Builder getServiceIdBuilder() {
-        
-        onChanged();
-        return getServiceIdFieldBuilder().getBuilder();
       }
-      /**
-       * <pre>
-       * Affected service and devices
-       * </pre>
-       *
-       * <code>.context.ServiceId serviceId = 8;</code>
-       */
-      public context.ContextOuterClass.ServiceIdOrBuilder getServiceIdOrBuilder() {
-        if (serviceIdBuilder_ != null) {
-          return serviceIdBuilder_.getMessageOrBuilder();
+
+      public Builder mergeFrom(policy.Policy.PolicyRuleServiceList other) {
+        if (other == policy.Policy.PolicyRuleServiceList.getDefaultInstance()) return this;
+        if (policyRuleServiceListBuilder_ == null) {
+          if (!other.policyRuleServiceList_.isEmpty()) {
+            if (policyRuleServiceList_.isEmpty()) {
+              policyRuleServiceList_ = other.policyRuleServiceList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+            } else {
+              ensurePolicyRuleServiceListIsMutable();
+              policyRuleServiceList_.addAll(other.policyRuleServiceList_);
+            }
+            onChanged();
+          }
         } else {
-          return serviceId_ == null ?
-              context.ContextOuterClass.ServiceId.getDefaultInstance() : serviceId_;
+          if (!other.policyRuleServiceList_.isEmpty()) {
+            if (policyRuleServiceListBuilder_.isEmpty()) {
+              policyRuleServiceListBuilder_.dispose();
+              policyRuleServiceListBuilder_ = null;
+              policyRuleServiceList_ = other.policyRuleServiceList_;
+              bitField0_ = (bitField0_ & ~0x00000001);
+              policyRuleServiceListBuilder_ = 
+                com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
+                   getPolicyRuleServiceListFieldBuilder() : null;
+            } else {
+              policyRuleServiceListBuilder_.addAllMessages(other.policyRuleServiceList_);
+            }
+          }
         }
+        this.mergeUnknownFields(other.unknownFields);
+        onChanged();
+        return this;
       }
-      /**
-       * <pre>
-       * Affected service and devices
-       * </pre>
-       *
-       * <code>.context.ServiceId serviceId = 8;</code>
-       */
-      private com.google.protobuf.SingleFieldBuilderV3<
-          context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder> 
-          getServiceIdFieldBuilder() {
-        if (serviceIdBuilder_ == null) {
-          serviceIdBuilder_ = new com.google.protobuf.SingleFieldBuilderV3<
-              context.ContextOuterClass.ServiceId, context.ContextOuterClass.ServiceId.Builder, context.ContextOuterClass.ServiceIdOrBuilder>(
-                  getServiceId(),
-                  getParentForChildren(),
-                  isClean());
-          serviceId_ = null;
+
+      @java.lang.Override
+      public final boolean isInitialized() {
+        return true;
+      }
+
+      @java.lang.Override
+      public Builder mergeFrom(
+          com.google.protobuf.CodedInputStream input,
+          com.google.protobuf.ExtensionRegistryLite extensionRegistry)
+          throws java.io.IOException {
+        policy.Policy.PolicyRuleServiceList parsedMessage = null;
+        try {
+          parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
+        } catch (com.google.protobuf.InvalidProtocolBufferException e) {
+          parsedMessage = (policy.Policy.PolicyRuleServiceList) e.getUnfinishedMessage();
+          throw e.unwrapIOException();
+        } finally {
+          if (parsedMessage != null) {
+            mergeFrom(parsedMessage);
+          }
         }
-        return serviceIdBuilder_;
+        return this;
       }
+      private int bitField0_;
 
-      private java.util.List<context.ContextOuterClass.DeviceId> deviceList_ =
+      private java.util.List<policy.Policy.PolicyRuleService> policyRuleServiceList_ =
         java.util.Collections.emptyList();
-      private void ensureDeviceListIsMutable() {
-        if (!((bitField0_ & 0x00000004) != 0)) {
-          deviceList_ = new java.util.ArrayList<context.ContextOuterClass.DeviceId>(deviceList_);
-          bitField0_ |= 0x00000004;
+      private void ensurePolicyRuleServiceListIsMutable() {
+        if (!((bitField0_ & 0x00000001) != 0)) {
+          policyRuleServiceList_ = new java.util.ArrayList<policy.Policy.PolicyRuleService>(policyRuleServiceList_);
+          bitField0_ |= 0x00000001;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder> deviceListBuilder_;
+          policy.Policy.PolicyRuleService, policy.Policy.PolicyRuleService.Builder, policy.Policy.PolicyRuleServiceOrBuilder> policyRuleServiceListBuilder_;
 
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public java.util.List<context.ContextOuterClass.DeviceId> getDeviceListList() {
-        if (deviceListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(deviceList_);
+      public java.util.List<policy.Policy.PolicyRuleService> getPolicyRuleServiceListList() {
+        if (policyRuleServiceListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(policyRuleServiceList_);
         } else {
-          return deviceListBuilder_.getMessageList();
+          return policyRuleServiceListBuilder_.getMessageList();
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public int getDeviceListCount() {
-        if (deviceListBuilder_ == null) {
-          return deviceList_.size();
+      public int getPolicyRuleServiceListCount() {
+        if (policyRuleServiceListBuilder_ == null) {
+          return policyRuleServiceList_.size();
         } else {
-          return deviceListBuilder_.getCount();
+          return policyRuleServiceListBuilder_.getCount();
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public context.ContextOuterClass.DeviceId getDeviceList(int index) {
-        if (deviceListBuilder_ == null) {
-          return deviceList_.get(index);
+      public policy.Policy.PolicyRuleService getPolicyRuleServiceList(int index) {
+        if (policyRuleServiceListBuilder_ == null) {
+          return policyRuleServiceList_.get(index);
         } else {
-          return deviceListBuilder_.getMessage(index);
+          return policyRuleServiceListBuilder_.getMessage(index);
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public Builder setDeviceList(
-          int index, context.ContextOuterClass.DeviceId value) {
-        if (deviceListBuilder_ == null) {
+      public Builder setPolicyRuleServiceList(
+          int index, policy.Policy.PolicyRuleService value) {
+        if (policyRuleServiceListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureDeviceListIsMutable();
-          deviceList_.set(index, value);
+          ensurePolicyRuleServiceListIsMutable();
+          policyRuleServiceList_.set(index, value);
           onChanged();
         } else {
-          deviceListBuilder_.setMessage(index, value);
+          policyRuleServiceListBuilder_.setMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public Builder setDeviceList(
-          int index, context.ContextOuterClass.DeviceId.Builder builderForValue) {
-        if (deviceListBuilder_ == null) {
-          ensureDeviceListIsMutable();
-          deviceList_.set(index, builderForValue.build());
+      public Builder setPolicyRuleServiceList(
+          int index, policy.Policy.PolicyRuleService.Builder builderForValue) {
+        if (policyRuleServiceListBuilder_ == null) {
+          ensurePolicyRuleServiceListIsMutable();
+          policyRuleServiceList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          deviceListBuilder_.setMessage(index, builderForValue.build());
+          policyRuleServiceListBuilder_.setMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public Builder addDeviceList(context.ContextOuterClass.DeviceId value) {
-        if (deviceListBuilder_ == null) {
+      public Builder addPolicyRuleServiceList(policy.Policy.PolicyRuleService value) {
+        if (policyRuleServiceListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureDeviceListIsMutable();
-          deviceList_.add(value);
+          ensurePolicyRuleServiceListIsMutable();
+          policyRuleServiceList_.add(value);
           onChanged();
         } else {
-          deviceListBuilder_.addMessage(value);
+          policyRuleServiceListBuilder_.addMessage(value);
         }
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public Builder addDeviceList(
-          int index, context.ContextOuterClass.DeviceId value) {
-        if (deviceListBuilder_ == null) {
+      public Builder addPolicyRuleServiceList(
+          int index, policy.Policy.PolicyRuleService value) {
+        if (policyRuleServiceListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensureDeviceListIsMutable();
-          deviceList_.add(index, value);
+          ensurePolicyRuleServiceListIsMutable();
+          policyRuleServiceList_.add(index, value);
           onChanged();
         } else {
-          deviceListBuilder_.addMessage(index, value);
+          policyRuleServiceListBuilder_.addMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public Builder addDeviceList(
-          context.ContextOuterClass.DeviceId.Builder builderForValue) {
-        if (deviceListBuilder_ == null) {
-          ensureDeviceListIsMutable();
-          deviceList_.add(builderForValue.build());
+      public Builder addPolicyRuleServiceList(
+          policy.Policy.PolicyRuleService.Builder builderForValue) {
+        if (policyRuleServiceListBuilder_ == null) {
+          ensurePolicyRuleServiceListIsMutable();
+          policyRuleServiceList_.add(builderForValue.build());
           onChanged();
         } else {
-          deviceListBuilder_.addMessage(builderForValue.build());
+          policyRuleServiceListBuilder_.addMessage(builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public Builder addDeviceList(
-          int index, context.ContextOuterClass.DeviceId.Builder builderForValue) {
-        if (deviceListBuilder_ == null) {
-          ensureDeviceListIsMutable();
-          deviceList_.add(index, builderForValue.build());
+      public Builder addPolicyRuleServiceList(
+          int index, policy.Policy.PolicyRuleService.Builder builderForValue) {
+        if (policyRuleServiceListBuilder_ == null) {
+          ensurePolicyRuleServiceListIsMutable();
+          policyRuleServiceList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          deviceListBuilder_.addMessage(index, builderForValue.build());
+          policyRuleServiceListBuilder_.addMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public Builder addAllDeviceList(
-          java.lang.Iterable<? extends context.ContextOuterClass.DeviceId> values) {
-        if (deviceListBuilder_ == null) {
-          ensureDeviceListIsMutable();
+      public Builder addAllPolicyRuleServiceList(
+          java.lang.Iterable<? extends policy.Policy.PolicyRuleService> values) {
+        if (policyRuleServiceListBuilder_ == null) {
+          ensurePolicyRuleServiceListIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, deviceList_);
+              values, policyRuleServiceList_);
           onChanged();
         } else {
-          deviceListBuilder_.addAllMessages(values);
+          policyRuleServiceListBuilder_.addAllMessages(values);
         }
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public Builder clearDeviceList() {
-        if (deviceListBuilder_ == null) {
-          deviceList_ = java.util.Collections.emptyList();
-          bitField0_ = (bitField0_ & ~0x00000004);
+      public Builder clearPolicyRuleServiceList() {
+        if (policyRuleServiceListBuilder_ == null) {
+          policyRuleServiceList_ = java.util.Collections.emptyList();
+          bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          deviceListBuilder_.clear();
+          policyRuleServiceListBuilder_.clear();
         }
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public Builder removeDeviceList(int index) {
-        if (deviceListBuilder_ == null) {
-          ensureDeviceListIsMutable();
-          deviceList_.remove(index);
+      public Builder removePolicyRuleServiceList(int index) {
+        if (policyRuleServiceListBuilder_ == null) {
+          ensurePolicyRuleServiceListIsMutable();
+          policyRuleServiceList_.remove(index);
           onChanged();
         } else {
-          deviceListBuilder_.remove(index);
+          policyRuleServiceListBuilder_.remove(index);
         }
         return this;
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public context.ContextOuterClass.DeviceId.Builder getDeviceListBuilder(
+      public policy.Policy.PolicyRuleService.Builder getPolicyRuleServiceListBuilder(
           int index) {
-        return getDeviceListFieldBuilder().getBuilder(index);
+        return getPolicyRuleServiceListFieldBuilder().getBuilder(index);
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public context.ContextOuterClass.DeviceIdOrBuilder getDeviceListOrBuilder(
+      public policy.Policy.PolicyRuleServiceOrBuilder getPolicyRuleServiceListOrBuilder(
           int index) {
-        if (deviceListBuilder_ == null) {
-          return deviceList_.get(index);  } else {
-          return deviceListBuilder_.getMessageOrBuilder(index);
+        if (policyRuleServiceListBuilder_ == null) {
+          return policyRuleServiceList_.get(index);  } else {
+          return policyRuleServiceListBuilder_.getMessageOrBuilder(index);
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public java.util.List<? extends context.ContextOuterClass.DeviceIdOrBuilder> 
-           getDeviceListOrBuilderList() {
-        if (deviceListBuilder_ != null) {
-          return deviceListBuilder_.getMessageOrBuilderList();
+      public java.util.List<? extends policy.Policy.PolicyRuleServiceOrBuilder> 
+           getPolicyRuleServiceListOrBuilderList() {
+        if (policyRuleServiceListBuilder_ != null) {
+          return policyRuleServiceListBuilder_.getMessageOrBuilderList();
         } else {
-          return java.util.Collections.unmodifiableList(deviceList_);
+          return java.util.Collections.unmodifiableList(policyRuleServiceList_);
         }
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public context.ContextOuterClass.DeviceId.Builder addDeviceListBuilder() {
-        return getDeviceListFieldBuilder().addBuilder(
-            context.ContextOuterClass.DeviceId.getDefaultInstance());
+      public policy.Policy.PolicyRuleService.Builder addPolicyRuleServiceListBuilder() {
+        return getPolicyRuleServiceListFieldBuilder().addBuilder(
+            policy.Policy.PolicyRuleService.getDefaultInstance());
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public context.ContextOuterClass.DeviceId.Builder addDeviceListBuilder(
+      public policy.Policy.PolicyRuleService.Builder addPolicyRuleServiceListBuilder(
           int index) {
-        return getDeviceListFieldBuilder().addBuilder(
-            index, context.ContextOuterClass.DeviceId.getDefaultInstance());
+        return getPolicyRuleServiceListFieldBuilder().addBuilder(
+            index, policy.Policy.PolicyRuleService.getDefaultInstance());
       }
       /**
-       * <code>repeated .context.DeviceId deviceList = 9;</code>
+       * <code>repeated .policy.PolicyRuleService policyRuleServiceList = 1;</code>
        */
-      public java.util.List<context.ContextOuterClass.DeviceId.Builder> 
-           getDeviceListBuilderList() {
-        return getDeviceListFieldBuilder().getBuilderList();
+      public java.util.List<policy.Policy.PolicyRuleService.Builder> 
+           getPolicyRuleServiceListBuilderList() {
+        return getPolicyRuleServiceListFieldBuilder().getBuilderList();
       }
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder> 
-          getDeviceListFieldBuilder() {
-        if (deviceListBuilder_ == null) {
-          deviceListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              context.ContextOuterClass.DeviceId, context.ContextOuterClass.DeviceId.Builder, context.ContextOuterClass.DeviceIdOrBuilder>(
-                  deviceList_,
-                  ((bitField0_ & 0x00000004) != 0),
+          policy.Policy.PolicyRuleService, policy.Policy.PolicyRuleService.Builder, policy.Policy.PolicyRuleServiceOrBuilder> 
+          getPolicyRuleServiceListFieldBuilder() {
+        if (policyRuleServiceListBuilder_ == null) {
+          policyRuleServiceListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              policy.Policy.PolicyRuleService, policy.Policy.PolicyRuleService.Builder, policy.Policy.PolicyRuleServiceOrBuilder>(
+                  policyRuleServiceList_,
+                  ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          deviceList_ = null;
+          policyRuleServiceList_ = null;
         }
-        return deviceListBuilder_;
+        return policyRuleServiceListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -5105,99 +7638,99 @@ public final class Policy {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:policy.PolicyRule)
+      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleServiceList)
     }
 
-    // @@protoc_insertion_point(class_scope:policy.PolicyRule)
-    private static final policy.Policy.PolicyRule DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:policy.PolicyRuleServiceList)
+    private static final policy.Policy.PolicyRuleServiceList DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new policy.Policy.PolicyRule();
+      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleServiceList();
     }
 
-    public static policy.Policy.PolicyRule getDefaultInstance() {
+    public static policy.Policy.PolicyRuleServiceList getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<PolicyRule>
-        PARSER = new com.google.protobuf.AbstractParser<PolicyRule>() {
+    private static final com.google.protobuf.Parser<PolicyRuleServiceList>
+        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleServiceList>() {
       @java.lang.Override
-      public PolicyRule parsePartialFrom(
+      public PolicyRuleServiceList parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new PolicyRule(input, extensionRegistry);
+        return new PolicyRuleServiceList(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<PolicyRule> parser() {
+    public static com.google.protobuf.Parser<PolicyRuleServiceList> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<PolicyRule> getParserForType() {
+    public com.google.protobuf.Parser<PolicyRuleServiceList> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public policy.Policy.PolicyRule getDefaultInstanceForType() {
+    public policy.Policy.PolicyRuleServiceList getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
   }
 
-  public interface PolicyRuleListOrBuilder extends
-      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleList)
+  public interface PolicyRuleDeviceListOrBuilder extends
+      // @@protoc_insertion_point(interface_extends:policy.PolicyRuleDeviceList)
       com.google.protobuf.MessageOrBuilder {
 
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
-    java.util.List<policy.Policy.PolicyRule> 
-        getPolicyRuleListList();
+    java.util.List<policy.Policy.PolicyRuleDevice> 
+        getPolicyRuleDeviceListList();
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
-    policy.Policy.PolicyRule getPolicyRuleList(int index);
+    policy.Policy.PolicyRuleDevice getPolicyRuleDeviceList(int index);
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
-    int getPolicyRuleListCount();
+    int getPolicyRuleDeviceListCount();
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
-    java.util.List<? extends policy.Policy.PolicyRuleOrBuilder> 
-        getPolicyRuleListOrBuilderList();
+    java.util.List<? extends policy.Policy.PolicyRuleDeviceOrBuilder> 
+        getPolicyRuleDeviceListOrBuilderList();
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
-    policy.Policy.PolicyRuleOrBuilder getPolicyRuleListOrBuilder(
+    policy.Policy.PolicyRuleDeviceOrBuilder getPolicyRuleDeviceListOrBuilder(
         int index);
   }
   /**
    * <pre>
-   * A list of policy rules
+   * A list of device-oriented policy rules
    * </pre>
    *
-   * Protobuf type {@code policy.PolicyRuleList}
+   * Protobuf type {@code policy.PolicyRuleDeviceList}
    */
-  public static final class PolicyRuleList extends
+  public static final class PolicyRuleDeviceList extends
       com.google.protobuf.GeneratedMessageV3 implements
-      // @@protoc_insertion_point(message_implements:policy.PolicyRuleList)
-      PolicyRuleListOrBuilder {
+      // @@protoc_insertion_point(message_implements:policy.PolicyRuleDeviceList)
+      PolicyRuleDeviceListOrBuilder {
   private static final long serialVersionUID = 0L;
-    // Use PolicyRuleList.newBuilder() to construct.
-    private PolicyRuleList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
+    // Use PolicyRuleDeviceList.newBuilder() to construct.
+    private PolicyRuleDeviceList(com.google.protobuf.GeneratedMessageV3.Builder<?> builder) {
       super(builder);
     }
-    private PolicyRuleList() {
-      policyRuleList_ = java.util.Collections.emptyList();
+    private PolicyRuleDeviceList() {
+      policyRuleDeviceList_ = java.util.Collections.emptyList();
     }
 
     @java.lang.Override
     @SuppressWarnings({"unused"})
     protected java.lang.Object newInstance(
         UnusedPrivateParameter unused) {
-      return new PolicyRuleList();
+      return new PolicyRuleDeviceList();
     }
 
     @java.lang.Override
@@ -5205,7 +7738,7 @@ public final class Policy {
     getUnknownFields() {
       return this.unknownFields;
     }
-    private PolicyRuleList(
+    private PolicyRuleDeviceList(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
@@ -5226,11 +7759,11 @@ public final class Policy {
               break;
             case 10: {
               if (!((mutable_bitField0_ & 0x00000001) != 0)) {
-                policyRuleList_ = new java.util.ArrayList<policy.Policy.PolicyRule>();
+                policyRuleDeviceList_ = new java.util.ArrayList<policy.Policy.PolicyRuleDevice>();
                 mutable_bitField0_ |= 0x00000001;
               }
-              policyRuleList_.add(
-                  input.readMessage(policy.Policy.PolicyRule.parser(), extensionRegistry));
+              policyRuleDeviceList_.add(
+                  input.readMessage(policy.Policy.PolicyRuleDevice.parser(), extensionRegistry));
               break;
             }
             default: {
@@ -5249,7 +7782,7 @@ public final class Policy {
             e).setUnfinishedMessage(this);
       } finally {
         if (((mutable_bitField0_ & 0x00000001) != 0)) {
-          policyRuleList_ = java.util.Collections.unmodifiableList(policyRuleList_);
+          policyRuleDeviceList_ = java.util.Collections.unmodifiableList(policyRuleDeviceList_);
         }
         this.unknownFields = unknownFields.build();
         makeExtensionsImmutable();
@@ -5257,55 +7790,55 @@ public final class Policy {
     }
     public static final com.google.protobuf.Descriptors.Descriptor
         getDescriptor() {
-      return policy.Policy.internal_static_policy_PolicyRuleList_descriptor;
+      return policy.Policy.internal_static_policy_PolicyRuleDeviceList_descriptor;
     }
 
     @java.lang.Override
     protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
         internalGetFieldAccessorTable() {
-      return policy.Policy.internal_static_policy_PolicyRuleList_fieldAccessorTable
+      return policy.Policy.internal_static_policy_PolicyRuleDeviceList_fieldAccessorTable
           .ensureFieldAccessorsInitialized(
-              policy.Policy.PolicyRuleList.class, policy.Policy.PolicyRuleList.Builder.class);
+              policy.Policy.PolicyRuleDeviceList.class, policy.Policy.PolicyRuleDeviceList.Builder.class);
     }
 
-    public static final int POLICYRULELIST_FIELD_NUMBER = 1;
-    private java.util.List<policy.Policy.PolicyRule> policyRuleList_;
+    public static final int POLICYRULEDEVICELIST_FIELD_NUMBER = 1;
+    private java.util.List<policy.Policy.PolicyRuleDevice> policyRuleDeviceList_;
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<policy.Policy.PolicyRule> getPolicyRuleListList() {
-      return policyRuleList_;
+    public java.util.List<policy.Policy.PolicyRuleDevice> getPolicyRuleDeviceListList() {
+      return policyRuleDeviceList_;
     }
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
     @java.lang.Override
-    public java.util.List<? extends policy.Policy.PolicyRuleOrBuilder> 
-        getPolicyRuleListOrBuilderList() {
-      return policyRuleList_;
+    public java.util.List<? extends policy.Policy.PolicyRuleDeviceOrBuilder> 
+        getPolicyRuleDeviceListOrBuilderList() {
+      return policyRuleDeviceList_;
     }
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
     @java.lang.Override
-    public int getPolicyRuleListCount() {
-      return policyRuleList_.size();
+    public int getPolicyRuleDeviceListCount() {
+      return policyRuleDeviceList_.size();
     }
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
     @java.lang.Override
-    public policy.Policy.PolicyRule getPolicyRuleList(int index) {
-      return policyRuleList_.get(index);
+    public policy.Policy.PolicyRuleDevice getPolicyRuleDeviceList(int index) {
+      return policyRuleDeviceList_.get(index);
     }
     /**
-     * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+     * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
      */
     @java.lang.Override
-    public policy.Policy.PolicyRuleOrBuilder getPolicyRuleListOrBuilder(
+    public policy.Policy.PolicyRuleDeviceOrBuilder getPolicyRuleDeviceListOrBuilder(
         int index) {
-      return policyRuleList_.get(index);
+      return policyRuleDeviceList_.get(index);
     }
 
     private byte memoizedIsInitialized = -1;
@@ -5322,8 +7855,8 @@ public final class Policy {
     @java.lang.Override
     public void writeTo(com.google.protobuf.CodedOutputStream output)
                         throws java.io.IOException {
-      for (int i = 0; i < policyRuleList_.size(); i++) {
-        output.writeMessage(1, policyRuleList_.get(i));
+      for (int i = 0; i < policyRuleDeviceList_.size(); i++) {
+        output.writeMessage(1, policyRuleDeviceList_.get(i));
       }
       unknownFields.writeTo(output);
     }
@@ -5334,9 +7867,9 @@ public final class Policy {
       if (size != -1) return size;
 
       size = 0;
-      for (int i = 0; i < policyRuleList_.size(); i++) {
+      for (int i = 0; i < policyRuleDeviceList_.size(); i++) {
         size += com.google.protobuf.CodedOutputStream
-          .computeMessageSize(1, policyRuleList_.get(i));
+          .computeMessageSize(1, policyRuleDeviceList_.get(i));
       }
       size += unknownFields.getSerializedSize();
       memoizedSize = size;
@@ -5348,13 +7881,13 @@ public final class Policy {
       if (obj == this) {
        return true;
       }
-      if (!(obj instanceof policy.Policy.PolicyRuleList)) {
+      if (!(obj instanceof policy.Policy.PolicyRuleDeviceList)) {
         return super.equals(obj);
       }
-      policy.Policy.PolicyRuleList other = (policy.Policy.PolicyRuleList) obj;
+      policy.Policy.PolicyRuleDeviceList other = (policy.Policy.PolicyRuleDeviceList) obj;
 
-      if (!getPolicyRuleListList()
-          .equals(other.getPolicyRuleListList())) return false;
+      if (!getPolicyRuleDeviceListList()
+          .equals(other.getPolicyRuleDeviceListList())) return false;
       if (!unknownFields.equals(other.unknownFields)) return false;
       return true;
     }
@@ -5366,78 +7899,78 @@ public final class Policy {
       }
       int hash = 41;
       hash = (19 * hash) + getDescriptor().hashCode();
-      if (getPolicyRuleListCount() > 0) {
-        hash = (37 * hash) + POLICYRULELIST_FIELD_NUMBER;
-        hash = (53 * hash) + getPolicyRuleListList().hashCode();
+      if (getPolicyRuleDeviceListCount() > 0) {
+        hash = (37 * hash) + POLICYRULEDEVICELIST_FIELD_NUMBER;
+        hash = (53 * hash) + getPolicyRuleDeviceListList().hashCode();
       }
       hash = (29 * hash) + unknownFields.hashCode();
       memoizedHashCode = hash;
       return hash;
     }
 
-    public static policy.Policy.PolicyRuleList parseFrom(
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(
         java.nio.ByteBuffer data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRuleList parseFrom(
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(
         java.nio.ByteBuffer data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleList parseFrom(
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(
         com.google.protobuf.ByteString data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRuleList parseFrom(
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(
         com.google.protobuf.ByteString data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleList parseFrom(byte[] data)
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(byte[] data)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data);
     }
-    public static policy.Policy.PolicyRuleList parseFrom(
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(
         byte[] data,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws com.google.protobuf.InvalidProtocolBufferException {
       return PARSER.parseFrom(data, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleList parseFrom(java.io.InputStream input)
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRuleList parseFrom(
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleList parseDelimitedFrom(java.io.InputStream input)
+    public static policy.Policy.PolicyRuleDeviceList parseDelimitedFrom(java.io.InputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRuleList parseDelimitedFrom(
+    public static policy.Policy.PolicyRuleDeviceList parseDelimitedFrom(
         java.io.InputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseDelimitedWithIOException(PARSER, input, extensionRegistry);
     }
-    public static policy.Policy.PolicyRuleList parseFrom(
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(
         com.google.protobuf.CodedInputStream input)
         throws java.io.IOException {
       return com.google.protobuf.GeneratedMessageV3
           .parseWithIOException(PARSER, input);
     }
-    public static policy.Policy.PolicyRuleList parseFrom(
+    public static policy.Policy.PolicyRuleDeviceList parseFrom(
         com.google.protobuf.CodedInputStream input,
         com.google.protobuf.ExtensionRegistryLite extensionRegistry)
         throws java.io.IOException {
@@ -5450,7 +7983,7 @@ public final class Policy {
     public static Builder newBuilder() {
       return DEFAULT_INSTANCE.toBuilder();
     }
-    public static Builder newBuilder(policy.Policy.PolicyRuleList prototype) {
+    public static Builder newBuilder(policy.Policy.PolicyRuleDeviceList prototype) {
       return DEFAULT_INSTANCE.toBuilder().mergeFrom(prototype);
     }
     @java.lang.Override
@@ -5467,29 +8000,29 @@ public final class Policy {
     }
     /**
      * <pre>
-     * A list of policy rules
+     * A list of device-oriented policy rules
      * </pre>
      *
-     * Protobuf type {@code policy.PolicyRuleList}
+     * Protobuf type {@code policy.PolicyRuleDeviceList}
      */
     public static final class Builder extends
         com.google.protobuf.GeneratedMessageV3.Builder<Builder> implements
-        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleList)
-        policy.Policy.PolicyRuleListOrBuilder {
+        // @@protoc_insertion_point(builder_implements:policy.PolicyRuleDeviceList)
+        policy.Policy.PolicyRuleDeviceListOrBuilder {
       public static final com.google.protobuf.Descriptors.Descriptor
           getDescriptor() {
-        return policy.Policy.internal_static_policy_PolicyRuleList_descriptor;
+        return policy.Policy.internal_static_policy_PolicyRuleDeviceList_descriptor;
       }
 
       @java.lang.Override
       protected com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
           internalGetFieldAccessorTable() {
-        return policy.Policy.internal_static_policy_PolicyRuleList_fieldAccessorTable
+        return policy.Policy.internal_static_policy_PolicyRuleDeviceList_fieldAccessorTable
             .ensureFieldAccessorsInitialized(
-                policy.Policy.PolicyRuleList.class, policy.Policy.PolicyRuleList.Builder.class);
+                policy.Policy.PolicyRuleDeviceList.class, policy.Policy.PolicyRuleDeviceList.Builder.class);
       }
 
-      // Construct using policy.Policy.PolicyRuleList.newBuilder()
+      // Construct using policy.Policy.PolicyRuleDeviceList.newBuilder()
       private Builder() {
         maybeForceBuilderInitialization();
       }
@@ -5502,17 +8035,17 @@ public final class Policy {
       private void maybeForceBuilderInitialization() {
         if (com.google.protobuf.GeneratedMessageV3
                 .alwaysUseFieldBuilders) {
-          getPolicyRuleListFieldBuilder();
+          getPolicyRuleDeviceListFieldBuilder();
         }
       }
       @java.lang.Override
       public Builder clear() {
         super.clear();
-        if (policyRuleListBuilder_ == null) {
-          policyRuleList_ = java.util.Collections.emptyList();
+        if (policyRuleDeviceListBuilder_ == null) {
+          policyRuleDeviceList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
         } else {
-          policyRuleListBuilder_.clear();
+          policyRuleDeviceListBuilder_.clear();
         }
         return this;
       }
@@ -5520,17 +8053,17 @@ public final class Policy {
       @java.lang.Override
       public com.google.protobuf.Descriptors.Descriptor
           getDescriptorForType() {
-        return policy.Policy.internal_static_policy_PolicyRuleList_descriptor;
+        return policy.Policy.internal_static_policy_PolicyRuleDeviceList_descriptor;
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRuleList getDefaultInstanceForType() {
-        return policy.Policy.PolicyRuleList.getDefaultInstance();
+      public policy.Policy.PolicyRuleDeviceList getDefaultInstanceForType() {
+        return policy.Policy.PolicyRuleDeviceList.getDefaultInstance();
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRuleList build() {
-        policy.Policy.PolicyRuleList result = buildPartial();
+      public policy.Policy.PolicyRuleDeviceList build() {
+        policy.Policy.PolicyRuleDeviceList result = buildPartial();
         if (!result.isInitialized()) {
           throw newUninitializedMessageException(result);
         }
@@ -5538,17 +8071,17 @@ public final class Policy {
       }
 
       @java.lang.Override
-      public policy.Policy.PolicyRuleList buildPartial() {
-        policy.Policy.PolicyRuleList result = new policy.Policy.PolicyRuleList(this);
+      public policy.Policy.PolicyRuleDeviceList buildPartial() {
+        policy.Policy.PolicyRuleDeviceList result = new policy.Policy.PolicyRuleDeviceList(this);
         int from_bitField0_ = bitField0_;
-        if (policyRuleListBuilder_ == null) {
+        if (policyRuleDeviceListBuilder_ == null) {
           if (((bitField0_ & 0x00000001) != 0)) {
-            policyRuleList_ = java.util.Collections.unmodifiableList(policyRuleList_);
+            policyRuleDeviceList_ = java.util.Collections.unmodifiableList(policyRuleDeviceList_);
             bitField0_ = (bitField0_ & ~0x00000001);
           }
-          result.policyRuleList_ = policyRuleList_;
+          result.policyRuleDeviceList_ = policyRuleDeviceList_;
         } else {
-          result.policyRuleList_ = policyRuleListBuilder_.build();
+          result.policyRuleDeviceList_ = policyRuleDeviceListBuilder_.build();
         }
         onBuilt();
         return result;
@@ -5588,39 +8121,39 @@ public final class Policy {
       }
       @java.lang.Override
       public Builder mergeFrom(com.google.protobuf.Message other) {
-        if (other instanceof policy.Policy.PolicyRuleList) {
-          return mergeFrom((policy.Policy.PolicyRuleList)other);
+        if (other instanceof policy.Policy.PolicyRuleDeviceList) {
+          return mergeFrom((policy.Policy.PolicyRuleDeviceList)other);
         } else {
           super.mergeFrom(other);
           return this;
         }
       }
 
-      public Builder mergeFrom(policy.Policy.PolicyRuleList other) {
-        if (other == policy.Policy.PolicyRuleList.getDefaultInstance()) return this;
-        if (policyRuleListBuilder_ == null) {
-          if (!other.policyRuleList_.isEmpty()) {
-            if (policyRuleList_.isEmpty()) {
-              policyRuleList_ = other.policyRuleList_;
+      public Builder mergeFrom(policy.Policy.PolicyRuleDeviceList other) {
+        if (other == policy.Policy.PolicyRuleDeviceList.getDefaultInstance()) return this;
+        if (policyRuleDeviceListBuilder_ == null) {
+          if (!other.policyRuleDeviceList_.isEmpty()) {
+            if (policyRuleDeviceList_.isEmpty()) {
+              policyRuleDeviceList_ = other.policyRuleDeviceList_;
               bitField0_ = (bitField0_ & ~0x00000001);
             } else {
-              ensurePolicyRuleListIsMutable();
-              policyRuleList_.addAll(other.policyRuleList_);
+              ensurePolicyRuleDeviceListIsMutable();
+              policyRuleDeviceList_.addAll(other.policyRuleDeviceList_);
             }
             onChanged();
           }
         } else {
-          if (!other.policyRuleList_.isEmpty()) {
-            if (policyRuleListBuilder_.isEmpty()) {
-              policyRuleListBuilder_.dispose();
-              policyRuleListBuilder_ = null;
-              policyRuleList_ = other.policyRuleList_;
+          if (!other.policyRuleDeviceList_.isEmpty()) {
+            if (policyRuleDeviceListBuilder_.isEmpty()) {
+              policyRuleDeviceListBuilder_.dispose();
+              policyRuleDeviceListBuilder_ = null;
+              policyRuleDeviceList_ = other.policyRuleDeviceList_;
               bitField0_ = (bitField0_ & ~0x00000001);
-              policyRuleListBuilder_ = 
+              policyRuleDeviceListBuilder_ = 
                 com.google.protobuf.GeneratedMessageV3.alwaysUseFieldBuilders ?
-                   getPolicyRuleListFieldBuilder() : null;
+                   getPolicyRuleDeviceListFieldBuilder() : null;
             } else {
-              policyRuleListBuilder_.addAllMessages(other.policyRuleList_);
+              policyRuleDeviceListBuilder_.addAllMessages(other.policyRuleDeviceList_);
             }
           }
         }
@@ -5639,11 +8172,11 @@ public final class Policy {
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws java.io.IOException {
-        policy.Policy.PolicyRuleList parsedMessage = null;
+        policy.Policy.PolicyRuleDeviceList parsedMessage = null;
         try {
           parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry);
         } catch (com.google.protobuf.InvalidProtocolBufferException e) {
-          parsedMessage = (policy.Policy.PolicyRuleList) e.getUnfinishedMessage();
+          parsedMessage = (policy.Policy.PolicyRuleDeviceList) e.getUnfinishedMessage();
           throw e.unwrapIOException();
         } finally {
           if (parsedMessage != null) {
@@ -5654,244 +8187,244 @@ public final class Policy {
       }
       private int bitField0_;
 
-      private java.util.List<policy.Policy.PolicyRule> policyRuleList_ =
+      private java.util.List<policy.Policy.PolicyRuleDevice> policyRuleDeviceList_ =
         java.util.Collections.emptyList();
-      private void ensurePolicyRuleListIsMutable() {
+      private void ensurePolicyRuleDeviceListIsMutable() {
         if (!((bitField0_ & 0x00000001) != 0)) {
-          policyRuleList_ = new java.util.ArrayList<policy.Policy.PolicyRule>(policyRuleList_);
+          policyRuleDeviceList_ = new java.util.ArrayList<policy.Policy.PolicyRuleDevice>(policyRuleDeviceList_);
           bitField0_ |= 0x00000001;
          }
       }
 
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.Policy.PolicyRule, policy.Policy.PolicyRule.Builder, policy.Policy.PolicyRuleOrBuilder> policyRuleListBuilder_;
+          policy.Policy.PolicyRuleDevice, policy.Policy.PolicyRuleDevice.Builder, policy.Policy.PolicyRuleDeviceOrBuilder> policyRuleDeviceListBuilder_;
 
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public java.util.List<policy.Policy.PolicyRule> getPolicyRuleListList() {
-        if (policyRuleListBuilder_ == null) {
-          return java.util.Collections.unmodifiableList(policyRuleList_);
+      public java.util.List<policy.Policy.PolicyRuleDevice> getPolicyRuleDeviceListList() {
+        if (policyRuleDeviceListBuilder_ == null) {
+          return java.util.Collections.unmodifiableList(policyRuleDeviceList_);
         } else {
-          return policyRuleListBuilder_.getMessageList();
+          return policyRuleDeviceListBuilder_.getMessageList();
         }
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public int getPolicyRuleListCount() {
-        if (policyRuleListBuilder_ == null) {
-          return policyRuleList_.size();
+      public int getPolicyRuleDeviceListCount() {
+        if (policyRuleDeviceListBuilder_ == null) {
+          return policyRuleDeviceList_.size();
         } else {
-          return policyRuleListBuilder_.getCount();
+          return policyRuleDeviceListBuilder_.getCount();
         }
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public policy.Policy.PolicyRule getPolicyRuleList(int index) {
-        if (policyRuleListBuilder_ == null) {
-          return policyRuleList_.get(index);
+      public policy.Policy.PolicyRuleDevice getPolicyRuleDeviceList(int index) {
+        if (policyRuleDeviceListBuilder_ == null) {
+          return policyRuleDeviceList_.get(index);
         } else {
-          return policyRuleListBuilder_.getMessage(index);
+          return policyRuleDeviceListBuilder_.getMessage(index);
         }
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public Builder setPolicyRuleList(
-          int index, policy.Policy.PolicyRule value) {
-        if (policyRuleListBuilder_ == null) {
+      public Builder setPolicyRuleDeviceList(
+          int index, policy.Policy.PolicyRuleDevice value) {
+        if (policyRuleDeviceListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensurePolicyRuleListIsMutable();
-          policyRuleList_.set(index, value);
+          ensurePolicyRuleDeviceListIsMutable();
+          policyRuleDeviceList_.set(index, value);
           onChanged();
         } else {
-          policyRuleListBuilder_.setMessage(index, value);
+          policyRuleDeviceListBuilder_.setMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public Builder setPolicyRuleList(
-          int index, policy.Policy.PolicyRule.Builder builderForValue) {
-        if (policyRuleListBuilder_ == null) {
-          ensurePolicyRuleListIsMutable();
-          policyRuleList_.set(index, builderForValue.build());
+      public Builder setPolicyRuleDeviceList(
+          int index, policy.Policy.PolicyRuleDevice.Builder builderForValue) {
+        if (policyRuleDeviceListBuilder_ == null) {
+          ensurePolicyRuleDeviceListIsMutable();
+          policyRuleDeviceList_.set(index, builderForValue.build());
           onChanged();
         } else {
-          policyRuleListBuilder_.setMessage(index, builderForValue.build());
+          policyRuleDeviceListBuilder_.setMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public Builder addPolicyRuleList(policy.Policy.PolicyRule value) {
-        if (policyRuleListBuilder_ == null) {
+      public Builder addPolicyRuleDeviceList(policy.Policy.PolicyRuleDevice value) {
+        if (policyRuleDeviceListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensurePolicyRuleListIsMutable();
-          policyRuleList_.add(value);
+          ensurePolicyRuleDeviceListIsMutable();
+          policyRuleDeviceList_.add(value);
           onChanged();
         } else {
-          policyRuleListBuilder_.addMessage(value);
+          policyRuleDeviceListBuilder_.addMessage(value);
         }
         return this;
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public Builder addPolicyRuleList(
-          int index, policy.Policy.PolicyRule value) {
-        if (policyRuleListBuilder_ == null) {
+      public Builder addPolicyRuleDeviceList(
+          int index, policy.Policy.PolicyRuleDevice value) {
+        if (policyRuleDeviceListBuilder_ == null) {
           if (value == null) {
             throw new NullPointerException();
           }
-          ensurePolicyRuleListIsMutable();
-          policyRuleList_.add(index, value);
+          ensurePolicyRuleDeviceListIsMutable();
+          policyRuleDeviceList_.add(index, value);
           onChanged();
         } else {
-          policyRuleListBuilder_.addMessage(index, value);
+          policyRuleDeviceListBuilder_.addMessage(index, value);
         }
         return this;
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public Builder addPolicyRuleList(
-          policy.Policy.PolicyRule.Builder builderForValue) {
-        if (policyRuleListBuilder_ == null) {
-          ensurePolicyRuleListIsMutable();
-          policyRuleList_.add(builderForValue.build());
+      public Builder addPolicyRuleDeviceList(
+          policy.Policy.PolicyRuleDevice.Builder builderForValue) {
+        if (policyRuleDeviceListBuilder_ == null) {
+          ensurePolicyRuleDeviceListIsMutable();
+          policyRuleDeviceList_.add(builderForValue.build());
           onChanged();
         } else {
-          policyRuleListBuilder_.addMessage(builderForValue.build());
+          policyRuleDeviceListBuilder_.addMessage(builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public Builder addPolicyRuleList(
-          int index, policy.Policy.PolicyRule.Builder builderForValue) {
-        if (policyRuleListBuilder_ == null) {
-          ensurePolicyRuleListIsMutable();
-          policyRuleList_.add(index, builderForValue.build());
+      public Builder addPolicyRuleDeviceList(
+          int index, policy.Policy.PolicyRuleDevice.Builder builderForValue) {
+        if (policyRuleDeviceListBuilder_ == null) {
+          ensurePolicyRuleDeviceListIsMutable();
+          policyRuleDeviceList_.add(index, builderForValue.build());
           onChanged();
         } else {
-          policyRuleListBuilder_.addMessage(index, builderForValue.build());
+          policyRuleDeviceListBuilder_.addMessage(index, builderForValue.build());
         }
         return this;
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public Builder addAllPolicyRuleList(
-          java.lang.Iterable<? extends policy.Policy.PolicyRule> values) {
-        if (policyRuleListBuilder_ == null) {
-          ensurePolicyRuleListIsMutable();
+      public Builder addAllPolicyRuleDeviceList(
+          java.lang.Iterable<? extends policy.Policy.PolicyRuleDevice> values) {
+        if (policyRuleDeviceListBuilder_ == null) {
+          ensurePolicyRuleDeviceListIsMutable();
           com.google.protobuf.AbstractMessageLite.Builder.addAll(
-              values, policyRuleList_);
+              values, policyRuleDeviceList_);
           onChanged();
         } else {
-          policyRuleListBuilder_.addAllMessages(values);
+          policyRuleDeviceListBuilder_.addAllMessages(values);
         }
         return this;
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public Builder clearPolicyRuleList() {
-        if (policyRuleListBuilder_ == null) {
-          policyRuleList_ = java.util.Collections.emptyList();
+      public Builder clearPolicyRuleDeviceList() {
+        if (policyRuleDeviceListBuilder_ == null) {
+          policyRuleDeviceList_ = java.util.Collections.emptyList();
           bitField0_ = (bitField0_ & ~0x00000001);
           onChanged();
         } else {
-          policyRuleListBuilder_.clear();
+          policyRuleDeviceListBuilder_.clear();
         }
         return this;
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public Builder removePolicyRuleList(int index) {
-        if (policyRuleListBuilder_ == null) {
-          ensurePolicyRuleListIsMutable();
-          policyRuleList_.remove(index);
+      public Builder removePolicyRuleDeviceList(int index) {
+        if (policyRuleDeviceListBuilder_ == null) {
+          ensurePolicyRuleDeviceListIsMutable();
+          policyRuleDeviceList_.remove(index);
           onChanged();
         } else {
-          policyRuleListBuilder_.remove(index);
+          policyRuleDeviceListBuilder_.remove(index);
         }
         return this;
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public policy.Policy.PolicyRule.Builder getPolicyRuleListBuilder(
+      public policy.Policy.PolicyRuleDevice.Builder getPolicyRuleDeviceListBuilder(
           int index) {
-        return getPolicyRuleListFieldBuilder().getBuilder(index);
+        return getPolicyRuleDeviceListFieldBuilder().getBuilder(index);
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public policy.Policy.PolicyRuleOrBuilder getPolicyRuleListOrBuilder(
+      public policy.Policy.PolicyRuleDeviceOrBuilder getPolicyRuleDeviceListOrBuilder(
           int index) {
-        if (policyRuleListBuilder_ == null) {
-          return policyRuleList_.get(index);  } else {
-          return policyRuleListBuilder_.getMessageOrBuilder(index);
+        if (policyRuleDeviceListBuilder_ == null) {
+          return policyRuleDeviceList_.get(index);  } else {
+          return policyRuleDeviceListBuilder_.getMessageOrBuilder(index);
         }
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public java.util.List<? extends policy.Policy.PolicyRuleOrBuilder> 
-           getPolicyRuleListOrBuilderList() {
-        if (policyRuleListBuilder_ != null) {
-          return policyRuleListBuilder_.getMessageOrBuilderList();
+      public java.util.List<? extends policy.Policy.PolicyRuleDeviceOrBuilder> 
+           getPolicyRuleDeviceListOrBuilderList() {
+        if (policyRuleDeviceListBuilder_ != null) {
+          return policyRuleDeviceListBuilder_.getMessageOrBuilderList();
         } else {
-          return java.util.Collections.unmodifiableList(policyRuleList_);
+          return java.util.Collections.unmodifiableList(policyRuleDeviceList_);
         }
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public policy.Policy.PolicyRule.Builder addPolicyRuleListBuilder() {
-        return getPolicyRuleListFieldBuilder().addBuilder(
-            policy.Policy.PolicyRule.getDefaultInstance());
+      public policy.Policy.PolicyRuleDevice.Builder addPolicyRuleDeviceListBuilder() {
+        return getPolicyRuleDeviceListFieldBuilder().addBuilder(
+            policy.Policy.PolicyRuleDevice.getDefaultInstance());
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public policy.Policy.PolicyRule.Builder addPolicyRuleListBuilder(
+      public policy.Policy.PolicyRuleDevice.Builder addPolicyRuleDeviceListBuilder(
           int index) {
-        return getPolicyRuleListFieldBuilder().addBuilder(
-            index, policy.Policy.PolicyRule.getDefaultInstance());
+        return getPolicyRuleDeviceListFieldBuilder().addBuilder(
+            index, policy.Policy.PolicyRuleDevice.getDefaultInstance());
       }
       /**
-       * <code>repeated .policy.PolicyRule policyRuleList = 1;</code>
+       * <code>repeated .policy.PolicyRuleDevice policyRuleDeviceList = 1;</code>
        */
-      public java.util.List<policy.Policy.PolicyRule.Builder> 
-           getPolicyRuleListBuilderList() {
-        return getPolicyRuleListFieldBuilder().getBuilderList();
+      public java.util.List<policy.Policy.PolicyRuleDevice.Builder> 
+           getPolicyRuleDeviceListBuilderList() {
+        return getPolicyRuleDeviceListFieldBuilder().getBuilderList();
       }
       private com.google.protobuf.RepeatedFieldBuilderV3<
-          policy.Policy.PolicyRule, policy.Policy.PolicyRule.Builder, policy.Policy.PolicyRuleOrBuilder> 
-          getPolicyRuleListFieldBuilder() {
-        if (policyRuleListBuilder_ == null) {
-          policyRuleListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
-              policy.Policy.PolicyRule, policy.Policy.PolicyRule.Builder, policy.Policy.PolicyRuleOrBuilder>(
-                  policyRuleList_,
+          policy.Policy.PolicyRuleDevice, policy.Policy.PolicyRuleDevice.Builder, policy.Policy.PolicyRuleDeviceOrBuilder> 
+          getPolicyRuleDeviceListFieldBuilder() {
+        if (policyRuleDeviceListBuilder_ == null) {
+          policyRuleDeviceListBuilder_ = new com.google.protobuf.RepeatedFieldBuilderV3<
+              policy.Policy.PolicyRuleDevice, policy.Policy.PolicyRuleDevice.Builder, policy.Policy.PolicyRuleDeviceOrBuilder>(
+                  policyRuleDeviceList_,
                   ((bitField0_ & 0x00000001) != 0),
                   getParentForChildren(),
                   isClean());
-          policyRuleList_ = null;
+          policyRuleDeviceList_ = null;
         }
-        return policyRuleListBuilder_;
+        return policyRuleDeviceListBuilder_;
       }
       @java.lang.Override
       public final Builder setUnknownFields(
@@ -5906,41 +8439,41 @@ public final class Policy {
       }
 
 
-      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleList)
+      // @@protoc_insertion_point(builder_scope:policy.PolicyRuleDeviceList)
     }
 
-    // @@protoc_insertion_point(class_scope:policy.PolicyRuleList)
-    private static final policy.Policy.PolicyRuleList DEFAULT_INSTANCE;
+    // @@protoc_insertion_point(class_scope:policy.PolicyRuleDeviceList)
+    private static final policy.Policy.PolicyRuleDeviceList DEFAULT_INSTANCE;
     static {
-      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleList();
+      DEFAULT_INSTANCE = new policy.Policy.PolicyRuleDeviceList();
     }
 
-    public static policy.Policy.PolicyRuleList getDefaultInstance() {
+    public static policy.Policy.PolicyRuleDeviceList getDefaultInstance() {
       return DEFAULT_INSTANCE;
     }
 
-    private static final com.google.protobuf.Parser<PolicyRuleList>
-        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleList>() {
+    private static final com.google.protobuf.Parser<PolicyRuleDeviceList>
+        PARSER = new com.google.protobuf.AbstractParser<PolicyRuleDeviceList>() {
       @java.lang.Override
-      public PolicyRuleList parsePartialFrom(
+      public PolicyRuleDeviceList parsePartialFrom(
           com.google.protobuf.CodedInputStream input,
           com.google.protobuf.ExtensionRegistryLite extensionRegistry)
           throws com.google.protobuf.InvalidProtocolBufferException {
-        return new PolicyRuleList(input, extensionRegistry);
+        return new PolicyRuleDeviceList(input, extensionRegistry);
       }
     };
 
-    public static com.google.protobuf.Parser<PolicyRuleList> parser() {
+    public static com.google.protobuf.Parser<PolicyRuleDeviceList> parser() {
       return PARSER;
     }
 
     @java.lang.Override
-    public com.google.protobuf.Parser<PolicyRuleList> getParserForType() {
+    public com.google.protobuf.Parser<PolicyRuleDeviceList> getParserForType() {
       return PARSER;
     }
 
     @java.lang.Override
-    public policy.Policy.PolicyRuleList getDefaultInstanceForType() {
+    public policy.Policy.PolicyRuleDeviceList getDefaultInstanceForType() {
       return DEFAULT_INSTANCE;
     }
 
@@ -5957,20 +8490,35 @@ public final class Policy {
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
       internal_static_policy_PolicyRuleState_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_policy_PolicyRuleEvent_descriptor;
+    internal_static_policy_PolicyRuleBasic_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_policy_PolicyRuleBasic_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_policy_PolicyRuleService_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_policy_PolicyRuleService_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_policy_PolicyRuleDevice_descriptor;
+  private static final 
+    com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
+      internal_static_policy_PolicyRuleDevice_fieldAccessorTable;
+  private static final com.google.protobuf.Descriptors.Descriptor
+    internal_static_policy_PolicyRuleIdList_descriptor;
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_policy_PolicyRuleEvent_fieldAccessorTable;
+      internal_static_policy_PolicyRuleIdList_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_policy_PolicyRule_descriptor;
+    internal_static_policy_PolicyRuleServiceList_descriptor;
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_policy_PolicyRule_fieldAccessorTable;
+      internal_static_policy_PolicyRuleServiceList_fieldAccessorTable;
   private static final com.google.protobuf.Descriptors.Descriptor
-    internal_static_policy_PolicyRuleList_descriptor;
+    internal_static_policy_PolicyRuleDeviceList_descriptor;
   private static final 
     com.google.protobuf.GeneratedMessageV3.FieldAccessorTable
-      internal_static_policy_PolicyRuleList_fieldAccessorTable;
+      internal_static_policy_PolicyRuleDeviceList_fieldAccessorTable;
 
   public static com.google.protobuf.Descriptors.FileDescriptor
       getDescriptor() {
@@ -5983,35 +8531,49 @@ public final class Policy {
       "\n\014policy.proto\022\006policy\032\rcontext.proto\032\026p" +
       "olicy-condition.proto\032\023policy-action.pro" +
       "to\"+\n\014PolicyRuleId\022\033\n\004uuid\030\001 \001(\0132\r.conte" +
-      "xt.Uuid\"b\n\017PolicyRuleState\022#\n\014policyRule" +
-      "Id\030\001 \001(\0132\r.context.Uuid\022*\n\017policyRuleSta" +
-      "te\030\002 \001(\0162\021.policy.RuleState\"0\n\017PolicyRul" +
-      "eEvent\022\035\n\005event\030\001 \001(\0132\016.context.Event\"\204\003" +
-      "\n\nPolicyRule\022*\n\014policyRuleId\030\001 \001(\0132\024.pol" +
-      "icy.PolicyRuleId\022.\n\016policyRuleType\030\002 \001(\016" +
-      "2\026.policy.PolicyRuleType\022\020\n\010priority\030\003 \001" +
-      "(\r\022&\n\005event\030\004 \001(\0132\027.policy.PolicyRuleEve" +
-      "nt\0222\n\rconditionList\030\005 \003(\0132\033.policy.Polic" +
-      "yRuleCondition\0220\n\017booleanOperator\030\006 \001(\0162" +
-      "\027.policy.BooleanOperator\022,\n\nactionList\030\007" +
-      " \003(\0132\030.policy.PolicyRuleAction\022%\n\tservic" +
-      "eId\030\010 \001(\0132\022.context.ServiceId\022%\n\ndeviceL" +
-      "ist\030\t \003(\0132\021.context.DeviceId\"<\n\016PolicyRu" +
-      "leList\022*\n\016policyRuleList\030\001 \003(\0132\022.policy." +
-      "PolicyRule*G\n\tRuleState\022\023\n\017POLICY_INACTI" +
-      "VE\020\000\022\022\n\016POLICY_PLANNED\020\001\022\021\n\rPOLICY_ACTIV" +
-      "E\020\002*?\n\016PolicyRuleType\022\025\n\021POLICYTYPE_DEVI" +
-      "CE\020\000\022\026\n\022POLICYTYPE_NETWORK\020\0012\214\003\n\rPolicyS" +
-      "ervice\022:\n\tPolicyAdd\022\022.policy.PolicyRule\032" +
-      "\027.policy.PolicyRuleState\"\000\022=\n\014PolicyUpda" +
-      "te\022\022.policy.PolicyRule\032\027.policy.PolicyRu" +
-      "leState\"\000\022=\n\014PolicyDelete\022\022.policy.Polic" +
-      "yRule\032\027.policy.PolicyRuleState\"\000\0227\n\tGetP" +
-      "olicy\022\024.policy.PolicyRuleId\032\022.policy.Pol" +
-      "icyRule\"\000\022B\n\023GetPolicyByDeviceId\022\021.conte" +
-      "xt.DeviceId\032\026.policy.PolicyRuleList\"\000\022D\n" +
-      "\024GetPolicyByServiceId\022\022.context.ServiceI" +
-      "d\032\026.policy.PolicyRuleList\"\000b\006proto3"
+      "xt.Uuid\"=\n\017PolicyRuleState\022*\n\017policyRule" +
+      "State\030\001 \001(\0162\021.policy.RuleState\"\256\002\n\017Polic" +
+      "yRuleBasic\022*\n\014policyRuleId\030\001 \001(\0132\024.polic" +
+      "y.PolicyRuleId\0225\n\017policyRuleState\030\002 \001(\0132" +
+      "\027.policy.PolicyRuleStateH\000\210\001\001\022\020\n\010priorit" +
+      "y\030\003 \001(\r\0222\n\rconditionList\030\004 \003(\0132\033.policy." +
+      "PolicyRuleCondition\0220\n\017booleanOperator\030\005" +
+      " \001(\0162\027.policy.BooleanOperator\022,\n\nactionL" +
+      "ist\030\006 \003(\0132\030.policy.PolicyRuleActionB\022\n\020_" +
+      "policyRuleState\"\223\001\n\021PolicyRuleService\0220\n" +
+      "\017policyRuleBasic\030\001 \001(\0132\027.policy.PolicyRu" +
+      "leBasic\022%\n\tserviceId\030\002 \001(\0132\022.context.Ser" +
+      "viceId\022%\n\ndeviceList\030\003 \003(\0132\021.context.Dev" +
+      "iceId\"k\n\020PolicyRuleDevice\0220\n\017policyRuleB" +
+      "asic\030\001 \001(\0132\027.policy.PolicyRuleBasic\022%\n\nd" +
+      "eviceList\030\002 \003(\0132\021.context.DeviceId\"B\n\020Po" +
+      "licyRuleIdList\022.\n\020policyRuleIdList\030\001 \003(\013" +
+      "2\024.policy.PolicyRuleId\"Q\n\025PolicyRuleServ" +
+      "iceList\0228\n\025policyRuleServiceList\030\001 \003(\0132\031" +
+      ".policy.PolicyRuleService\"N\n\024PolicyRuleD" +
+      "eviceList\0226\n\024policyRuleDeviceList\030\001 \003(\0132" +
+      "\030.policy.PolicyRuleDevice*\365\001\n\tRuleState\022" +
+      "\024\n\020POLICY_UNDEFINED\020\000\022\021\n\rPOLICY_FAILED\020\001" +
+      "\022\023\n\017POLICY_INSERTED\020\002\022\024\n\020POLICY_VALIDATE" +
+      "D\020\003\022\026\n\022POLICY_PROVISIONED\020\004\022\021\n\rPOLICY_AC" +
+      "TIVE\020\005\022\023\n\017POLICY_ENFORCED\020\006\022\026\n\022POLICY_IN" +
+      "EFFECTIVE\020\007\022\024\n\020POLICY_EFFECTIVE\020\010\022\022\n\016POL" +
+      "ICY_UPDATED\020\t\022\022\n\016POLICY_REMOVED\020\n2\323\004\n\rPo" +
+      "licyService\022H\n\020PolicyAddService\022\031.policy" +
+      ".PolicyRuleService\032\027.policy.PolicyRuleSt" +
+      "ate\"\000\022F\n\017PolicyAddDevice\022\030.policy.Policy" +
+      "RuleDevice\032\027.policy.PolicyRuleState\"\000\022K\n" +
+      "\023PolicyUpdateService\022\031.policy.PolicyRule" +
+      "Service\032\027.policy.PolicyRuleState\"\000\022I\n\022Po" +
+      "licyUpdateDevice\022\030.policy.PolicyRuleDevi" +
+      "ce\032\027.policy.PolicyRuleState\"\000\022?\n\014PolicyD" +
+      "elete\022\024.policy.PolicyRuleId\032\027.policy.Pol" +
+      "icyRuleState\"\000\022E\n\020GetPolicyService\022\024.pol" +
+      "icy.PolicyRuleId\032\031.policy.PolicyRuleServ" +
+      "ice\"\000\022C\n\017GetPolicyDevice\022\024.policy.Policy" +
+      "RuleId\032\030.policy.PolicyRuleDevice\"\000\022K\n\024Ge" +
+      "tPolicyByServiceId\022\022.context.ServiceId\032\035" +
+      ".policy.PolicyRuleServiceList\"\000b\006proto3"
     };
     descriptor = com.google.protobuf.Descriptors.FileDescriptor
       .internalBuildGeneratedFileFrom(descriptorData,
@@ -6031,25 +8593,43 @@ public final class Policy {
     internal_static_policy_PolicyRuleState_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
         internal_static_policy_PolicyRuleState_descriptor,
-        new java.lang.String[] { "PolicyRuleId", "PolicyRuleState", });
-    internal_static_policy_PolicyRuleEvent_descriptor =
+        new java.lang.String[] { "PolicyRuleState", });
+    internal_static_policy_PolicyRuleBasic_descriptor =
       getDescriptor().getMessageTypes().get(2);
-    internal_static_policy_PolicyRuleEvent_fieldAccessorTable = new
+    internal_static_policy_PolicyRuleBasic_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_policy_PolicyRuleEvent_descriptor,
-        new java.lang.String[] { "Event", });
-    internal_static_policy_PolicyRule_descriptor =
+        internal_static_policy_PolicyRuleBasic_descriptor,
+        new java.lang.String[] { "PolicyRuleId", "PolicyRuleState", "Priority", "ConditionList", "BooleanOperator", "ActionList", "PolicyRuleState", });
+    internal_static_policy_PolicyRuleService_descriptor =
       getDescriptor().getMessageTypes().get(3);
-    internal_static_policy_PolicyRule_fieldAccessorTable = new
+    internal_static_policy_PolicyRuleService_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_policy_PolicyRule_descriptor,
-        new java.lang.String[] { "PolicyRuleId", "PolicyRuleType", "Priority", "Event", "ConditionList", "BooleanOperator", "ActionList", "ServiceId", "DeviceList", });
-    internal_static_policy_PolicyRuleList_descriptor =
+        internal_static_policy_PolicyRuleService_descriptor,
+        new java.lang.String[] { "PolicyRuleBasic", "ServiceId", "DeviceList", });
+    internal_static_policy_PolicyRuleDevice_descriptor =
       getDescriptor().getMessageTypes().get(4);
-    internal_static_policy_PolicyRuleList_fieldAccessorTable = new
+    internal_static_policy_PolicyRuleDevice_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_policy_PolicyRuleDevice_descriptor,
+        new java.lang.String[] { "PolicyRuleBasic", "DeviceList", });
+    internal_static_policy_PolicyRuleIdList_descriptor =
+      getDescriptor().getMessageTypes().get(5);
+    internal_static_policy_PolicyRuleIdList_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_policy_PolicyRuleIdList_descriptor,
+        new java.lang.String[] { "PolicyRuleIdList", });
+    internal_static_policy_PolicyRuleServiceList_descriptor =
+      getDescriptor().getMessageTypes().get(6);
+    internal_static_policy_PolicyRuleServiceList_fieldAccessorTable = new
+      com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
+        internal_static_policy_PolicyRuleServiceList_descriptor,
+        new java.lang.String[] { "PolicyRuleServiceList", });
+    internal_static_policy_PolicyRuleDeviceList_descriptor =
+      getDescriptor().getMessageTypes().get(7);
+    internal_static_policy_PolicyRuleDeviceList_fieldAccessorTable = new
       com.google.protobuf.GeneratedMessageV3.FieldAccessorTable(
-        internal_static_policy_PolicyRuleList_descriptor,
-        new java.lang.String[] { "PolicyRuleList", });
+        internal_static_policy_PolicyRuleDeviceList_descriptor,
+        new java.lang.String[] { "PolicyRuleDeviceList", });
     context.ContextOuterClass.getDescriptor();
     policy.PolicyCondition.getDescriptor();
     policy.PolicyAction.getDescriptor();
diff --git a/src/policy/target/generated-sources/grpc/policy/PolicyService.java b/src/policy/target/generated-sources/grpc/policy/PolicyService.java
index 8c2e637f5..277fbbfc5 100644
--- a/src/policy/target/generated-sources/grpc/policy/PolicyService.java
+++ b/src/policy/target/generated-sources/grpc/policy/PolicyService.java
@@ -8,17 +8,21 @@ comments = "Source: policy.proto")
 public interface PolicyService extends MutinyService {
 
     
-    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAdd(policy.Policy.PolicyRule request);
+    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddService(policy.Policy.PolicyRuleService request);
     
-    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdate(policy.Policy.PolicyRule request);
+    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddDevice(policy.Policy.PolicyRuleDevice request);
     
-    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRule request);
+    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateService(policy.Policy.PolicyRuleService request);
     
-    io.smallrye.mutiny.Uni<policy.Policy.PolicyRule> getPolicy(policy.Policy.PolicyRuleId request);
+    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateDevice(policy.Policy.PolicyRuleDevice request);
     
-    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByDeviceId(context.ContextOuterClass.DeviceId request);
+    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRuleId request);
     
-    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request);
+    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleService> getPolicyService(policy.Policy.PolicyRuleId request);
+    
+    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleDevice> getPolicyDevice(policy.Policy.PolicyRuleId request);
+    
+    io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleServiceList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request);
     
     
     
diff --git a/src/policy/target/generated-sources/grpc/policy/PolicyServiceBean.java b/src/policy/target/generated-sources/grpc/policy/PolicyServiceBean.java
index 08c0e47d9..ada3eeaec 100644
--- a/src/policy/target/generated-sources/grpc/policy/PolicyServiceBean.java
+++ b/src/policy/target/generated-sources/grpc/policy/PolicyServiceBean.java
@@ -16,23 +16,39 @@ public class PolicyServiceBean extends MutinyPolicyServiceGrpc.PolicyServiceImpl
     }
 
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAdd(policy.Policy.PolicyRule request) {
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddService(policy.Policy.PolicyRuleService request) {
        try {
-         return delegate.policyAdd(request);
+         return delegate.policyAddService(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdate(policy.Policy.PolicyRule request) {
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddDevice(policy.Policy.PolicyRuleDevice request) {
        try {
-         return delegate.policyUpdate(request);
+         return delegate.policyAddDevice(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRule request) {
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateService(policy.Policy.PolicyRuleService request) {
+       try {
+         return delegate.policyUpdateService(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateDevice(policy.Policy.PolicyRuleDevice request) {
+       try {
+         return delegate.policyUpdateDevice(request);
+       } catch (UnsupportedOperationException e) {
+          throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
+       }
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRuleId request) {
        try {
          return delegate.policyDelete(request);
        } catch (UnsupportedOperationException e) {
@@ -40,23 +56,23 @@ public class PolicyServiceBean extends MutinyPolicyServiceGrpc.PolicyServiceImpl
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRule> getPolicy(policy.Policy.PolicyRuleId request) {
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleService> getPolicyService(policy.Policy.PolicyRuleId request) {
        try {
-         return delegate.getPolicy(request);
+         return delegate.getPolicyService(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByDeviceId(context.ContextOuterClass.DeviceId request) {
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleDevice> getPolicyDevice(policy.Policy.PolicyRuleId request) {
        try {
-         return delegate.getPolicyByDeviceId(request);
+         return delegate.getPolicyDevice(request);
        } catch (UnsupportedOperationException e) {
           throw new io.grpc.StatusRuntimeException(io.grpc.Status.UNIMPLEMENTED);
        }
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleServiceList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
        try {
          return delegate.getPolicyByServiceId(request);
        } catch (UnsupportedOperationException e) {
diff --git a/src/policy/target/generated-sources/grpc/policy/PolicyServiceClient.java b/src/policy/target/generated-sources/grpc/policy/PolicyServiceClient.java
index 6d4477197..5f5af2002 100644
--- a/src/policy/target/generated-sources/grpc/policy/PolicyServiceClient.java
+++ b/src/policy/target/generated-sources/grpc/policy/PolicyServiceClient.java
@@ -21,27 +21,35 @@ public class PolicyServiceClient implements PolicyService, MutinyClient<MutinyPo
     }
 
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAdd(policy.Policy.PolicyRule request) {
-       return stub.policyAdd(request);
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddService(policy.Policy.PolicyRuleService request) {
+       return stub.policyAddService(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdate(policy.Policy.PolicyRule request) {
-       return stub.policyUpdate(request);
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyAddDevice(policy.Policy.PolicyRuleDevice request) {
+       return stub.policyAddDevice(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRule request) {
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateService(policy.Policy.PolicyRuleService request) {
+       return stub.policyUpdateService(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyUpdateDevice(policy.Policy.PolicyRuleDevice request) {
+       return stub.policyUpdateDevice(request);
+    }
+    @Override
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleState> policyDelete(policy.Policy.PolicyRuleId request) {
        return stub.policyDelete(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRule> getPolicy(policy.Policy.PolicyRuleId request) {
-       return stub.getPolicy(request);
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleService> getPolicyService(policy.Policy.PolicyRuleId request) {
+       return stub.getPolicyService(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByDeviceId(context.ContextOuterClass.DeviceId request) {
-       return stub.getPolicyByDeviceId(request);
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleDevice> getPolicyDevice(policy.Policy.PolicyRuleId request) {
+       return stub.getPolicyDevice(request);
     }
     @Override
-    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
+    public io.smallrye.mutiny.Uni<policy.Policy.PolicyRuleServiceList> getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
        return stub.getPolicyByServiceId(request);
     }
 
diff --git a/src/policy/target/generated-sources/grpc/policy/PolicyServiceGrpc.java b/src/policy/target/generated-sources/grpc/policy/PolicyServiceGrpc.java
index 76cba3268..af57ac567 100644
--- a/src/policy/target/generated-sources/grpc/policy/PolicyServiceGrpc.java
+++ b/src/policy/target/generated-sources/grpc/policy/PolicyServiceGrpc.java
@@ -14,89 +14,151 @@ public final class PolicyServiceGrpc {
   public static final String SERVICE_NAME = "policy.PolicyService";
 
   // Static method descriptors that strictly reflect the proto.
-  private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRule,
-      policy.Policy.PolicyRuleState> getPolicyAddMethod;
+  private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRuleService,
+      policy.Policy.PolicyRuleState> getPolicyAddServiceMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "PolicyAdd",
-      requestType = policy.Policy.PolicyRule.class,
+      fullMethodName = SERVICE_NAME + '/' + "PolicyAddService",
+      requestType = policy.Policy.PolicyRuleService.class,
       responseType = policy.Policy.PolicyRuleState.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<policy.Policy.PolicyRule,
-      policy.Policy.PolicyRuleState> getPolicyAddMethod() {
-    io.grpc.MethodDescriptor<policy.Policy.PolicyRule, policy.Policy.PolicyRuleState> getPolicyAddMethod;
-    if ((getPolicyAddMethod = PolicyServiceGrpc.getPolicyAddMethod) == null) {
+  public static io.grpc.MethodDescriptor<policy.Policy.PolicyRuleService,
+      policy.Policy.PolicyRuleState> getPolicyAddServiceMethod() {
+    io.grpc.MethodDescriptor<policy.Policy.PolicyRuleService, policy.Policy.PolicyRuleState> getPolicyAddServiceMethod;
+    if ((getPolicyAddServiceMethod = PolicyServiceGrpc.getPolicyAddServiceMethod) == null) {
       synchronized (PolicyServiceGrpc.class) {
-        if ((getPolicyAddMethod = PolicyServiceGrpc.getPolicyAddMethod) == null) {
-          PolicyServiceGrpc.getPolicyAddMethod = getPolicyAddMethod =
-              io.grpc.MethodDescriptor.<policy.Policy.PolicyRule, policy.Policy.PolicyRuleState>newBuilder()
+        if ((getPolicyAddServiceMethod = PolicyServiceGrpc.getPolicyAddServiceMethod) == null) {
+          PolicyServiceGrpc.getPolicyAddServiceMethod = getPolicyAddServiceMethod =
+              io.grpc.MethodDescriptor.<policy.Policy.PolicyRuleService, policy.Policy.PolicyRuleState>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "PolicyAdd"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "PolicyAddService"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  policy.Policy.PolicyRule.getDefaultInstance()))
+                  policy.Policy.PolicyRuleService.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   policy.Policy.PolicyRuleState.getDefaultInstance()))
-              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("PolicyAdd"))
+              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("PolicyAddService"))
               .build();
         }
       }
     }
-    return getPolicyAddMethod;
+    return getPolicyAddServiceMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRule,
-      policy.Policy.PolicyRuleState> getPolicyUpdateMethod;
+  private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRuleDevice,
+      policy.Policy.PolicyRuleState> getPolicyAddDeviceMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "PolicyUpdate",
-      requestType = policy.Policy.PolicyRule.class,
+      fullMethodName = SERVICE_NAME + '/' + "PolicyAddDevice",
+      requestType = policy.Policy.PolicyRuleDevice.class,
       responseType = policy.Policy.PolicyRuleState.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<policy.Policy.PolicyRule,
-      policy.Policy.PolicyRuleState> getPolicyUpdateMethod() {
-    io.grpc.MethodDescriptor<policy.Policy.PolicyRule, policy.Policy.PolicyRuleState> getPolicyUpdateMethod;
-    if ((getPolicyUpdateMethod = PolicyServiceGrpc.getPolicyUpdateMethod) == null) {
+  public static io.grpc.MethodDescriptor<policy.Policy.PolicyRuleDevice,
+      policy.Policy.PolicyRuleState> getPolicyAddDeviceMethod() {
+    io.grpc.MethodDescriptor<policy.Policy.PolicyRuleDevice, policy.Policy.PolicyRuleState> getPolicyAddDeviceMethod;
+    if ((getPolicyAddDeviceMethod = PolicyServiceGrpc.getPolicyAddDeviceMethod) == null) {
       synchronized (PolicyServiceGrpc.class) {
-        if ((getPolicyUpdateMethod = PolicyServiceGrpc.getPolicyUpdateMethod) == null) {
-          PolicyServiceGrpc.getPolicyUpdateMethod = getPolicyUpdateMethod =
-              io.grpc.MethodDescriptor.<policy.Policy.PolicyRule, policy.Policy.PolicyRuleState>newBuilder()
+        if ((getPolicyAddDeviceMethod = PolicyServiceGrpc.getPolicyAddDeviceMethod) == null) {
+          PolicyServiceGrpc.getPolicyAddDeviceMethod = getPolicyAddDeviceMethod =
+              io.grpc.MethodDescriptor.<policy.Policy.PolicyRuleDevice, policy.Policy.PolicyRuleState>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "PolicyUpdate"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "PolicyAddDevice"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  policy.Policy.PolicyRule.getDefaultInstance()))
+                  policy.Policy.PolicyRuleDevice.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   policy.Policy.PolicyRuleState.getDefaultInstance()))
-              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("PolicyUpdate"))
+              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("PolicyAddDevice"))
               .build();
         }
       }
     }
-    return getPolicyUpdateMethod;
+    return getPolicyAddDeviceMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRule,
+  private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRuleService,
+      policy.Policy.PolicyRuleState> getPolicyUpdateServiceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "PolicyUpdateService",
+      requestType = policy.Policy.PolicyRuleService.class,
+      responseType = policy.Policy.PolicyRuleState.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<policy.Policy.PolicyRuleService,
+      policy.Policy.PolicyRuleState> getPolicyUpdateServiceMethod() {
+    io.grpc.MethodDescriptor<policy.Policy.PolicyRuleService, policy.Policy.PolicyRuleState> getPolicyUpdateServiceMethod;
+    if ((getPolicyUpdateServiceMethod = PolicyServiceGrpc.getPolicyUpdateServiceMethod) == null) {
+      synchronized (PolicyServiceGrpc.class) {
+        if ((getPolicyUpdateServiceMethod = PolicyServiceGrpc.getPolicyUpdateServiceMethod) == null) {
+          PolicyServiceGrpc.getPolicyUpdateServiceMethod = getPolicyUpdateServiceMethod =
+              io.grpc.MethodDescriptor.<policy.Policy.PolicyRuleService, policy.Policy.PolicyRuleState>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "PolicyUpdateService"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  policy.Policy.PolicyRuleService.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  policy.Policy.PolicyRuleState.getDefaultInstance()))
+              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("PolicyUpdateService"))
+              .build();
+        }
+      }
+    }
+    return getPolicyUpdateServiceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRuleDevice,
+      policy.Policy.PolicyRuleState> getPolicyUpdateDeviceMethod;
+
+  @io.grpc.stub.annotations.RpcMethod(
+      fullMethodName = SERVICE_NAME + '/' + "PolicyUpdateDevice",
+      requestType = policy.Policy.PolicyRuleDevice.class,
+      responseType = policy.Policy.PolicyRuleState.class,
+      methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
+  public static io.grpc.MethodDescriptor<policy.Policy.PolicyRuleDevice,
+      policy.Policy.PolicyRuleState> getPolicyUpdateDeviceMethod() {
+    io.grpc.MethodDescriptor<policy.Policy.PolicyRuleDevice, policy.Policy.PolicyRuleState> getPolicyUpdateDeviceMethod;
+    if ((getPolicyUpdateDeviceMethod = PolicyServiceGrpc.getPolicyUpdateDeviceMethod) == null) {
+      synchronized (PolicyServiceGrpc.class) {
+        if ((getPolicyUpdateDeviceMethod = PolicyServiceGrpc.getPolicyUpdateDeviceMethod) == null) {
+          PolicyServiceGrpc.getPolicyUpdateDeviceMethod = getPolicyUpdateDeviceMethod =
+              io.grpc.MethodDescriptor.<policy.Policy.PolicyRuleDevice, policy.Policy.PolicyRuleState>newBuilder()
+              .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "PolicyUpdateDevice"))
+              .setSampledToLocalTracing(true)
+              .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  policy.Policy.PolicyRuleDevice.getDefaultInstance()))
+              .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
+                  policy.Policy.PolicyRuleState.getDefaultInstance()))
+              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("PolicyUpdateDevice"))
+              .build();
+        }
+      }
+    }
+    return getPolicyUpdateDeviceMethod;
+  }
+
+  private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId,
       policy.Policy.PolicyRuleState> getPolicyDeleteMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
       fullMethodName = SERVICE_NAME + '/' + "PolicyDelete",
-      requestType = policy.Policy.PolicyRule.class,
+      requestType = policy.Policy.PolicyRuleId.class,
       responseType = policy.Policy.PolicyRuleState.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<policy.Policy.PolicyRule,
+  public static io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId,
       policy.Policy.PolicyRuleState> getPolicyDeleteMethod() {
-    io.grpc.MethodDescriptor<policy.Policy.PolicyRule, policy.Policy.PolicyRuleState> getPolicyDeleteMethod;
+    io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleState> getPolicyDeleteMethod;
     if ((getPolicyDeleteMethod = PolicyServiceGrpc.getPolicyDeleteMethod) == null) {
       synchronized (PolicyServiceGrpc.class) {
         if ((getPolicyDeleteMethod = PolicyServiceGrpc.getPolicyDeleteMethod) == null) {
           PolicyServiceGrpc.getPolicyDeleteMethod = getPolicyDeleteMethod =
-              io.grpc.MethodDescriptor.<policy.Policy.PolicyRule, policy.Policy.PolicyRuleState>newBuilder()
+              io.grpc.MethodDescriptor.<policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleState>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
               .setFullMethodName(generateFullMethodName(SERVICE_NAME, "PolicyDelete"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  policy.Policy.PolicyRule.getDefaultInstance()))
+                  policy.Policy.PolicyRuleId.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   policy.Policy.PolicyRuleState.getDefaultInstance()))
               .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("PolicyDelete"))
@@ -108,90 +170,90 @@ public final class PolicyServiceGrpc {
   }
 
   private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId,
-      policy.Policy.PolicyRule> getGetPolicyMethod;
+      policy.Policy.PolicyRuleService> getGetPolicyServiceMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "GetPolicy",
+      fullMethodName = SERVICE_NAME + '/' + "GetPolicyService",
       requestType = policy.Policy.PolicyRuleId.class,
-      responseType = policy.Policy.PolicyRule.class,
+      responseType = policy.Policy.PolicyRuleService.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
   public static io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId,
-      policy.Policy.PolicyRule> getGetPolicyMethod() {
-    io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId, policy.Policy.PolicyRule> getGetPolicyMethod;
-    if ((getGetPolicyMethod = PolicyServiceGrpc.getGetPolicyMethod) == null) {
+      policy.Policy.PolicyRuleService> getGetPolicyServiceMethod() {
+    io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleService> getGetPolicyServiceMethod;
+    if ((getGetPolicyServiceMethod = PolicyServiceGrpc.getGetPolicyServiceMethod) == null) {
       synchronized (PolicyServiceGrpc.class) {
-        if ((getGetPolicyMethod = PolicyServiceGrpc.getGetPolicyMethod) == null) {
-          PolicyServiceGrpc.getGetPolicyMethod = getGetPolicyMethod =
-              io.grpc.MethodDescriptor.<policy.Policy.PolicyRuleId, policy.Policy.PolicyRule>newBuilder()
+        if ((getGetPolicyServiceMethod = PolicyServiceGrpc.getGetPolicyServiceMethod) == null) {
+          PolicyServiceGrpc.getGetPolicyServiceMethod = getGetPolicyServiceMethod =
+              io.grpc.MethodDescriptor.<policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleService>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetPolicy"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetPolicyService"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   policy.Policy.PolicyRuleId.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  policy.Policy.PolicyRule.getDefaultInstance()))
-              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("GetPolicy"))
+                  policy.Policy.PolicyRuleService.getDefaultInstance()))
+              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("GetPolicyService"))
               .build();
         }
       }
     }
-    return getGetPolicyMethod;
+    return getGetPolicyServiceMethod;
   }
 
-  private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.DeviceId,
-      policy.Policy.PolicyRuleList> getGetPolicyByDeviceIdMethod;
+  private static volatile io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId,
+      policy.Policy.PolicyRuleDevice> getGetPolicyDeviceMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
-      fullMethodName = SERVICE_NAME + '/' + "GetPolicyByDeviceId",
-      requestType = context.ContextOuterClass.DeviceId.class,
-      responseType = policy.Policy.PolicyRuleList.class,
+      fullMethodName = SERVICE_NAME + '/' + "GetPolicyDevice",
+      requestType = policy.Policy.PolicyRuleId.class,
+      responseType = policy.Policy.PolicyRuleDevice.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
-  public static io.grpc.MethodDescriptor<context.ContextOuterClass.DeviceId,
-      policy.Policy.PolicyRuleList> getGetPolicyByDeviceIdMethod() {
-    io.grpc.MethodDescriptor<context.ContextOuterClass.DeviceId, policy.Policy.PolicyRuleList> getGetPolicyByDeviceIdMethod;
-    if ((getGetPolicyByDeviceIdMethod = PolicyServiceGrpc.getGetPolicyByDeviceIdMethod) == null) {
+  public static io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId,
+      policy.Policy.PolicyRuleDevice> getGetPolicyDeviceMethod() {
+    io.grpc.MethodDescriptor<policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleDevice> getGetPolicyDeviceMethod;
+    if ((getGetPolicyDeviceMethod = PolicyServiceGrpc.getGetPolicyDeviceMethod) == null) {
       synchronized (PolicyServiceGrpc.class) {
-        if ((getGetPolicyByDeviceIdMethod = PolicyServiceGrpc.getGetPolicyByDeviceIdMethod) == null) {
-          PolicyServiceGrpc.getGetPolicyByDeviceIdMethod = getGetPolicyByDeviceIdMethod =
-              io.grpc.MethodDescriptor.<context.ContextOuterClass.DeviceId, policy.Policy.PolicyRuleList>newBuilder()
+        if ((getGetPolicyDeviceMethod = PolicyServiceGrpc.getGetPolicyDeviceMethod) == null) {
+          PolicyServiceGrpc.getGetPolicyDeviceMethod = getGetPolicyDeviceMethod =
+              io.grpc.MethodDescriptor.<policy.Policy.PolicyRuleId, policy.Policy.PolicyRuleDevice>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
-              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetPolicyByDeviceId"))
+              .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetPolicyDevice"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  context.ContextOuterClass.DeviceId.getDefaultInstance()))
+                  policy.Policy.PolicyRuleId.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  policy.Policy.PolicyRuleList.getDefaultInstance()))
-              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("GetPolicyByDeviceId"))
+                  policy.Policy.PolicyRuleDevice.getDefaultInstance()))
+              .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("GetPolicyDevice"))
               .build();
         }
       }
     }
-    return getGetPolicyByDeviceIdMethod;
+    return getGetPolicyDeviceMethod;
   }
 
   private static volatile io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId,
-      policy.Policy.PolicyRuleList> getGetPolicyByServiceIdMethod;
+      policy.Policy.PolicyRuleServiceList> getGetPolicyByServiceIdMethod;
 
   @io.grpc.stub.annotations.RpcMethod(
       fullMethodName = SERVICE_NAME + '/' + "GetPolicyByServiceId",
       requestType = context.ContextOuterClass.ServiceId.class,
-      responseType = policy.Policy.PolicyRuleList.class,
+      responseType = policy.Policy.PolicyRuleServiceList.class,
       methodType = io.grpc.MethodDescriptor.MethodType.UNARY)
   public static io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId,
-      policy.Policy.PolicyRuleList> getGetPolicyByServiceIdMethod() {
-    io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId, policy.Policy.PolicyRuleList> getGetPolicyByServiceIdMethod;
+      policy.Policy.PolicyRuleServiceList> getGetPolicyByServiceIdMethod() {
+    io.grpc.MethodDescriptor<context.ContextOuterClass.ServiceId, policy.Policy.PolicyRuleServiceList> getGetPolicyByServiceIdMethod;
     if ((getGetPolicyByServiceIdMethod = PolicyServiceGrpc.getGetPolicyByServiceIdMethod) == null) {
       synchronized (PolicyServiceGrpc.class) {
         if ((getGetPolicyByServiceIdMethod = PolicyServiceGrpc.getGetPolicyByServiceIdMethod) == null) {
           PolicyServiceGrpc.getGetPolicyByServiceIdMethod = getGetPolicyByServiceIdMethod =
-              io.grpc.MethodDescriptor.<context.ContextOuterClass.ServiceId, policy.Policy.PolicyRuleList>newBuilder()
+              io.grpc.MethodDescriptor.<context.ContextOuterClass.ServiceId, policy.Policy.PolicyRuleServiceList>newBuilder()
               .setType(io.grpc.MethodDescriptor.MethodType.UNARY)
               .setFullMethodName(generateFullMethodName(SERVICE_NAME, "GetPolicyByServiceId"))
               .setSampledToLocalTracing(true)
               .setRequestMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
                   context.ContextOuterClass.ServiceId.getDefaultInstance()))
               .setResponseMarshaller(io.grpc.protobuf.ProtoUtils.marshaller(
-                  policy.Policy.PolicyRuleList.getDefaultInstance()))
+                  policy.Policy.PolicyRuleServiceList.getDefaultInstance()))
               .setSchemaDescriptor(new PolicyServiceMethodDescriptorSupplier("GetPolicyByServiceId"))
               .build();
         }
@@ -250,89 +312,117 @@ public final class PolicyServiceGrpc {
 
     /**
      */
-    public void policyAdd(policy.Policy.PolicyRule request,
+    public void policyAddService(policy.Policy.PolicyRuleService request,
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPolicyAddServiceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void policyAddDevice(policy.Policy.PolicyRuleDevice request,
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPolicyAddDeviceMethod(), responseObserver);
+    }
+
+    /**
+     */
+    public void policyUpdateService(policy.Policy.PolicyRuleService request,
         io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPolicyAddMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPolicyUpdateServiceMethod(), responseObserver);
     }
 
     /**
      */
-    public void policyUpdate(policy.Policy.PolicyRule request,
+    public void policyUpdateDevice(policy.Policy.PolicyRuleDevice request,
         io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPolicyUpdateMethod(), responseObserver);
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPolicyUpdateDeviceMethod(), responseObserver);
     }
 
     /**
      */
-    public void policyDelete(policy.Policy.PolicyRule request,
+    public void policyDelete(policy.Policy.PolicyRuleId request,
         io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getPolicyDeleteMethod(), responseObserver);
     }
 
     /**
      */
-    public void getPolicy(policy.Policy.PolicyRuleId request,
-        io.grpc.stub.StreamObserver<policy.Policy.PolicyRule> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetPolicyMethod(), responseObserver);
+    public void getPolicyService(policy.Policy.PolicyRuleId request,
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleService> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetPolicyServiceMethod(), responseObserver);
     }
 
     /**
      */
-    public void getPolicyByDeviceId(context.ContextOuterClass.DeviceId request,
-        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleList> responseObserver) {
-      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetPolicyByDeviceIdMethod(), responseObserver);
+    public void getPolicyDevice(policy.Policy.PolicyRuleId request,
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleDevice> responseObserver) {
+      io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetPolicyDeviceMethod(), responseObserver);
     }
 
     /**
      */
     public void getPolicyByServiceId(context.ContextOuterClass.ServiceId request,
-        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleList> responseObserver) {
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleServiceList> responseObserver) {
       io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall(getGetPolicyByServiceIdMethod(), responseObserver);
     }
 
     @java.lang.Override public final io.grpc.ServerServiceDefinition bindService() {
       return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
           .addMethod(
-            getPolicyAddMethod(),
+            getPolicyAddServiceMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                policy.Policy.PolicyRule,
+                policy.Policy.PolicyRuleService,
                 policy.Policy.PolicyRuleState>(
-                  this, METHODID_POLICY_ADD)))
+                  this, METHODID_POLICY_ADD_SERVICE)))
           .addMethod(
-            getPolicyUpdateMethod(),
+            getPolicyAddDeviceMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                policy.Policy.PolicyRule,
+                policy.Policy.PolicyRuleDevice,
                 policy.Policy.PolicyRuleState>(
-                  this, METHODID_POLICY_UPDATE)))
+                  this, METHODID_POLICY_ADD_DEVICE)))
+          .addMethod(
+            getPolicyUpdateServiceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                policy.Policy.PolicyRuleService,
+                policy.Policy.PolicyRuleState>(
+                  this, METHODID_POLICY_UPDATE_SERVICE)))
+          .addMethod(
+            getPolicyUpdateDeviceMethod(),
+            io.grpc.stub.ServerCalls.asyncUnaryCall(
+              new MethodHandlers<
+                policy.Policy.PolicyRuleDevice,
+                policy.Policy.PolicyRuleState>(
+                  this, METHODID_POLICY_UPDATE_DEVICE)))
           .addMethod(
             getPolicyDeleteMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                policy.Policy.PolicyRule,
+                policy.Policy.PolicyRuleId,
                 policy.Policy.PolicyRuleState>(
                   this, METHODID_POLICY_DELETE)))
           .addMethod(
-            getGetPolicyMethod(),
+            getGetPolicyServiceMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
                 policy.Policy.PolicyRuleId,
-                policy.Policy.PolicyRule>(
-                  this, METHODID_GET_POLICY)))
+                policy.Policy.PolicyRuleService>(
+                  this, METHODID_GET_POLICY_SERVICE)))
           .addMethod(
-            getGetPolicyByDeviceIdMethod(),
+            getGetPolicyDeviceMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
-                context.ContextOuterClass.DeviceId,
-                policy.Policy.PolicyRuleList>(
-                  this, METHODID_GET_POLICY_BY_DEVICE_ID)))
+                policy.Policy.PolicyRuleId,
+                policy.Policy.PolicyRuleDevice>(
+                  this, METHODID_GET_POLICY_DEVICE)))
           .addMethod(
             getGetPolicyByServiceIdMethod(),
             io.grpc.stub.ServerCalls.asyncUnaryCall(
               new MethodHandlers<
                 context.ContextOuterClass.ServiceId,
-                policy.Policy.PolicyRuleList>(
+                policy.Policy.PolicyRuleServiceList>(
                   this, METHODID_GET_POLICY_BY_SERVICE_ID)))
           .build();
     }
@@ -354,23 +444,39 @@ public final class PolicyServiceGrpc {
 
     /**
      */
-    public void policyAdd(policy.Policy.PolicyRule request,
+    public void policyAddService(policy.Policy.PolicyRuleService request,
         io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getPolicyAddMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getPolicyAddServiceMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
-    public void policyUpdate(policy.Policy.PolicyRule request,
+    public void policyAddDevice(policy.Policy.PolicyRuleDevice request,
         io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getPolicyUpdateMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getPolicyAddDeviceMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
-    public void policyDelete(policy.Policy.PolicyRule request,
+    public void policyUpdateService(policy.Policy.PolicyRuleService request,
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getPolicyUpdateServiceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void policyUpdateDevice(policy.Policy.PolicyRuleDevice request,
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
+      io.grpc.stub.ClientCalls.asyncUnaryCall(
+          getChannel().newCall(getPolicyUpdateDeviceMethod(), getCallOptions()), request, responseObserver);
+    }
+
+    /**
+     */
+    public void policyDelete(policy.Policy.PolicyRuleId request,
         io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
           getChannel().newCall(getPolicyDeleteMethod(), getCallOptions()), request, responseObserver);
@@ -378,24 +484,24 @@ public final class PolicyServiceGrpc {
 
     /**
      */
-    public void getPolicy(policy.Policy.PolicyRuleId request,
-        io.grpc.stub.StreamObserver<policy.Policy.PolicyRule> responseObserver) {
+    public void getPolicyService(policy.Policy.PolicyRuleId request,
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleService> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getGetPolicyMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getGetPolicyServiceMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
-    public void getPolicyByDeviceId(context.ContextOuterClass.DeviceId request,
-        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleList> responseObserver) {
+    public void getPolicyDevice(policy.Policy.PolicyRuleId request,
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleDevice> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
-          getChannel().newCall(getGetPolicyByDeviceIdMethod(), getCallOptions()), request, responseObserver);
+          getChannel().newCall(getGetPolicyDeviceMethod(), getCallOptions()), request, responseObserver);
     }
 
     /**
      */
     public void getPolicyByServiceId(context.ContextOuterClass.ServiceId request,
-        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleList> responseObserver) {
+        io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleServiceList> responseObserver) {
       io.grpc.stub.ClientCalls.asyncUnaryCall(
           getChannel().newCall(getGetPolicyByServiceIdMethod(), getCallOptions()), request, responseObserver);
     }
@@ -417,42 +523,56 @@ public final class PolicyServiceGrpc {
 
     /**
      */
-    public policy.Policy.PolicyRuleState policyAdd(policy.Policy.PolicyRule request) {
+    public policy.Policy.PolicyRuleState policyAddService(policy.Policy.PolicyRuleService request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getPolicyAddMethod(), getCallOptions(), request);
+          getChannel(), getPolicyAddServiceMethod(), getCallOptions(), request);
     }
 
     /**
      */
-    public policy.Policy.PolicyRuleState policyUpdate(policy.Policy.PolicyRule request) {
+    public policy.Policy.PolicyRuleState policyAddDevice(policy.Policy.PolicyRuleDevice request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getPolicyUpdateMethod(), getCallOptions(), request);
+          getChannel(), getPolicyAddDeviceMethod(), getCallOptions(), request);
     }
 
     /**
      */
-    public policy.Policy.PolicyRuleState policyDelete(policy.Policy.PolicyRule request) {
+    public policy.Policy.PolicyRuleState policyUpdateService(policy.Policy.PolicyRuleService request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getPolicyUpdateServiceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public policy.Policy.PolicyRuleState policyUpdateDevice(policy.Policy.PolicyRuleDevice request) {
+      return io.grpc.stub.ClientCalls.blockingUnaryCall(
+          getChannel(), getPolicyUpdateDeviceMethod(), getCallOptions(), request);
+    }
+
+    /**
+     */
+    public policy.Policy.PolicyRuleState policyDelete(policy.Policy.PolicyRuleId request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
           getChannel(), getPolicyDeleteMethod(), getCallOptions(), request);
     }
 
     /**
      */
-    public policy.Policy.PolicyRule getPolicy(policy.Policy.PolicyRuleId request) {
+    public policy.Policy.PolicyRuleService getPolicyService(policy.Policy.PolicyRuleId request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getGetPolicyMethod(), getCallOptions(), request);
+          getChannel(), getGetPolicyServiceMethod(), getCallOptions(), request);
     }
 
     /**
      */
-    public policy.Policy.PolicyRuleList getPolicyByDeviceId(context.ContextOuterClass.DeviceId request) {
+    public policy.Policy.PolicyRuleDevice getPolicyDevice(policy.Policy.PolicyRuleId request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
-          getChannel(), getGetPolicyByDeviceIdMethod(), getCallOptions(), request);
+          getChannel(), getGetPolicyDeviceMethod(), getCallOptions(), request);
     }
 
     /**
      */
-    public policy.Policy.PolicyRuleList getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
+    public policy.Policy.PolicyRuleServiceList getPolicyByServiceId(context.ContextOuterClass.ServiceId request) {
       return io.grpc.stub.ClientCalls.blockingUnaryCall(
           getChannel(), getGetPolicyByServiceIdMethod(), getCallOptions(), request);
     }
@@ -474,59 +594,77 @@ public final class PolicyServiceGrpc {
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleState> policyAdd(
-        policy.Policy.PolicyRule request) {
+    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleState> policyAddService(
+        policy.Policy.PolicyRuleService request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getPolicyAddServiceMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleState> policyAddDevice(
+        policy.Policy.PolicyRuleDevice request) {
+      return io.grpc.stub.ClientCalls.futureUnaryCall(
+          getChannel().newCall(getPolicyAddDeviceMethod(), getCallOptions()), request);
+    }
+
+    /**
+     */
+    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleState> policyUpdateService(
+        policy.Policy.PolicyRuleService request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getPolicyAddMethod(), getCallOptions()), request);
+          getChannel().newCall(getPolicyUpdateServiceMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleState> policyUpdate(
-        policy.Policy.PolicyRule request) {
+    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleState> policyUpdateDevice(
+        policy.Policy.PolicyRuleDevice request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getPolicyUpdateMethod(), getCallOptions()), request);
+          getChannel().newCall(getPolicyUpdateDeviceMethod(), getCallOptions()), request);
     }
 
     /**
      */
     public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleState> policyDelete(
-        policy.Policy.PolicyRule request) {
+        policy.Policy.PolicyRuleId request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
           getChannel().newCall(getPolicyDeleteMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRule> getPolicy(
+    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleService> getPolicyService(
         policy.Policy.PolicyRuleId request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getGetPolicyMethod(), getCallOptions()), request);
+          getChannel().newCall(getGetPolicyServiceMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleList> getPolicyByDeviceId(
-        context.ContextOuterClass.DeviceId request) {
+    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleDevice> getPolicyDevice(
+        policy.Policy.PolicyRuleId request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
-          getChannel().newCall(getGetPolicyByDeviceIdMethod(), getCallOptions()), request);
+          getChannel().newCall(getGetPolicyDeviceMethod(), getCallOptions()), request);
     }
 
     /**
      */
-    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleList> getPolicyByServiceId(
+    public com.google.common.util.concurrent.ListenableFuture<policy.Policy.PolicyRuleServiceList> getPolicyByServiceId(
         context.ContextOuterClass.ServiceId request) {
       return io.grpc.stub.ClientCalls.futureUnaryCall(
           getChannel().newCall(getGetPolicyByServiceIdMethod(), getCallOptions()), request);
     }
   }
 
-  private static final int METHODID_POLICY_ADD = 0;
-  private static final int METHODID_POLICY_UPDATE = 1;
-  private static final int METHODID_POLICY_DELETE = 2;
-  private static final int METHODID_GET_POLICY = 3;
-  private static final int METHODID_GET_POLICY_BY_DEVICE_ID = 4;
-  private static final int METHODID_GET_POLICY_BY_SERVICE_ID = 5;
+  private static final int METHODID_POLICY_ADD_SERVICE = 0;
+  private static final int METHODID_POLICY_ADD_DEVICE = 1;
+  private static final int METHODID_POLICY_UPDATE_SERVICE = 2;
+  private static final int METHODID_POLICY_UPDATE_DEVICE = 3;
+  private static final int METHODID_POLICY_DELETE = 4;
+  private static final int METHODID_GET_POLICY_SERVICE = 5;
+  private static final int METHODID_GET_POLICY_DEVICE = 6;
+  private static final int METHODID_GET_POLICY_BY_SERVICE_ID = 7;
 
   private static final class MethodHandlers<Req, Resp> implements
       io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
@@ -545,29 +683,37 @@ public final class PolicyServiceGrpc {
     @java.lang.SuppressWarnings("unchecked")
     public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
       switch (methodId) {
-        case METHODID_POLICY_ADD:
-          serviceImpl.policyAdd((policy.Policy.PolicyRule) request,
+        case METHODID_POLICY_ADD_SERVICE:
+          serviceImpl.policyAddService((policy.Policy.PolicyRuleService) request,
+              (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver);
+          break;
+        case METHODID_POLICY_ADD_DEVICE:
+          serviceImpl.policyAddDevice((policy.Policy.PolicyRuleDevice) request,
+              (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver);
+          break;
+        case METHODID_POLICY_UPDATE_SERVICE:
+          serviceImpl.policyUpdateService((policy.Policy.PolicyRuleService) request,
               (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver);
           break;
-        case METHODID_POLICY_UPDATE:
-          serviceImpl.policyUpdate((policy.Policy.PolicyRule) request,
+        case METHODID_POLICY_UPDATE_DEVICE:
+          serviceImpl.policyUpdateDevice((policy.Policy.PolicyRuleDevice) request,
               (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver);
           break;
         case METHODID_POLICY_DELETE:
-          serviceImpl.policyDelete((policy.Policy.PolicyRule) request,
+          serviceImpl.policyDelete((policy.Policy.PolicyRuleId) request,
               (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleState>) responseObserver);
           break;
-        case METHODID_GET_POLICY:
-          serviceImpl.getPolicy((policy.Policy.PolicyRuleId) request,
-              (io.grpc.stub.StreamObserver<policy.Policy.PolicyRule>) responseObserver);
+        case METHODID_GET_POLICY_SERVICE:
+          serviceImpl.getPolicyService((policy.Policy.PolicyRuleId) request,
+              (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleService>) responseObserver);
           break;
-        case METHODID_GET_POLICY_BY_DEVICE_ID:
-          serviceImpl.getPolicyByDeviceId((context.ContextOuterClass.DeviceId) request,
-              (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleList>) responseObserver);
+        case METHODID_GET_POLICY_DEVICE:
+          serviceImpl.getPolicyDevice((policy.Policy.PolicyRuleId) request,
+              (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleDevice>) responseObserver);
           break;
         case METHODID_GET_POLICY_BY_SERVICE_ID:
           serviceImpl.getPolicyByServiceId((context.ContextOuterClass.ServiceId) request,
-              (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleList>) responseObserver);
+              (io.grpc.stub.StreamObserver<policy.Policy.PolicyRuleServiceList>) responseObserver);
           break;
         default:
           throw new AssertionError();
@@ -630,11 +776,13 @@ public final class PolicyServiceGrpc {
         if (result == null) {
           serviceDescriptor = result = io.grpc.ServiceDescriptor.newBuilder(SERVICE_NAME)
               .setSchemaDescriptor(new PolicyServiceFileDescriptorSupplier())
-              .addMethod(getPolicyAddMethod())
-              .addMethod(getPolicyUpdateMethod())
+              .addMethod(getPolicyAddServiceMethod())
+              .addMethod(getPolicyAddDeviceMethod())
+              .addMethod(getPolicyUpdateServiceMethod())
+              .addMethod(getPolicyUpdateDeviceMethod())
               .addMethod(getPolicyDeleteMethod())
-              .addMethod(getGetPolicyMethod())
-              .addMethod(getGetPolicyByDeviceIdMethod())
+              .addMethod(getGetPolicyServiceMethod())
+              .addMethod(getGetPolicyDeviceMethod())
               .addMethod(getGetPolicyByServiceIdMethod())
               .build();
         }
diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml
index 462e59696..f63ffbc09 100644
--- a/src/policy/target/kubernetes/kubernetes.yml
+++ b/src/policy/target/kubernetes/kubernetes.yml
@@ -3,8 +3,8 @@ apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 2aa29b383ec7bf12dc985729978210239ea8a726
-    app.quarkus.io/build-timestamp: 2022-07-07 - 10:19:44 +0000
+    app.quarkus.io/commit-id: fa8ec6157a3cde9fcea029558241850993a6ab5a
+    app.quarkus.io/build-timestamp: 2022-07-11 - 13:58:36 +0000
   labels:
     app.kubernetes.io/name: policyservice
     app: policyservice
@@ -25,8 +25,8 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: 2aa29b383ec7bf12dc985729978210239ea8a726
-    app.quarkus.io/build-timestamp: 2022-07-07 - 10:19:44 +0000
+    app.quarkus.io/commit-id: fa8ec6157a3cde9fcea029558241850993a6ab5a
+    app.quarkus.io/build-timestamp: 2022-07-11 - 13:58:36 +0000
   labels:
     app: policyservice
     app.kubernetes.io/name: policyservice
@@ -39,8 +39,8 @@ spec:
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: 2aa29b383ec7bf12dc985729978210239ea8a726
-        app.quarkus.io/build-timestamp: 2022-07-07 - 10:19:44 +0000
+        app.quarkus.io/commit-id: fa8ec6157a3cde9fcea029558241850993a6ab5a
+        app.quarkus.io/build-timestamp: 2022-07-11 - 13:58:36 +0000
       labels:
         app: policyservice
         app.kubernetes.io/name: policyservice
@@ -51,12 +51,12 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
-            - name: MONITORING_SERVICE_HOST
-              value: monitoringservice
             - name: SERVICE_SERVICE_HOST
               value: serviceservice
             - name: CONTEXT_SERVICE_HOST
               value: contextservice
+            - name: MONITORING_SERVICE_HOST
+              value: monitoringservice
           image: registry.gitlab.com/teraflow-h2020/controller/policy:0.1.0
           imagePullPolicy: Always
           livenessProbe:
-- 
GitLab


From 3da206958a8475e377537666acb083f14df77cc3 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Wed, 13 Jul 2022 13:43:22 +0300
Subject: [PATCH 59/60] chore(policy): change gRPC port to 6060

---
 src/policy/src/main/resources/application.yml |  6 ++--
 src/policy/target/kubernetes/kubernetes.yml   | 28 +++++++++----------
 2 files changed, 17 insertions(+), 17 deletions(-)

diff --git a/src/policy/src/main/resources/application.yml b/src/policy/src/main/resources/application.yml
index 0f6f45931..9ccfae3aa 100644
--- a/src/policy/src/main/resources/application.yml
+++ b/src/policy/src/main/resources/application.yml
@@ -17,7 +17,7 @@ quarkus:
     path: teraflow-policy-banner.txt
   grpc:
     server:
-      port: 9999
+      port: 6060
       enable-reflection-service: true
     clients:
       context:
@@ -55,8 +55,8 @@ quarkus:
         host-port: 8080
         container-port: 8080
       grpc-server:
-        host-port: 9999
-        container-port: 9999
+        host-port: 6060
+        container-port: 6060
     env:
       vars:
         context-service-host: "contextservice"
diff --git a/src/policy/target/kubernetes/kubernetes.yml b/src/policy/target/kubernetes/kubernetes.yml
index f63ffbc09..c002153bf 100644
--- a/src/policy/target/kubernetes/kubernetes.yml
+++ b/src/policy/target/kubernetes/kubernetes.yml
@@ -3,20 +3,20 @@ apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: fa8ec6157a3cde9fcea029558241850993a6ab5a
-    app.quarkus.io/build-timestamp: 2022-07-11 - 13:58:36 +0000
+    app.quarkus.io/commit-id: 665bca2f1245843e8c99eaa1a2c5315a6c002417
+    app.quarkus.io/build-timestamp: 2022-07-13 - 10:42:51 +0000
   labels:
     app.kubernetes.io/name: policyservice
     app: policyservice
   name: policyservice
 spec:
   ports:
+    - name: grpc-server
+      port: 6060
+      targetPort: 6060
     - name: http
       port: 8080
       targetPort: 8080
-    - name: grpc-server
-      port: 9999
-      targetPort: 9999
   selector:
     app.kubernetes.io/name: policyservice
   type: ClusterIP
@@ -25,8 +25,8 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: fa8ec6157a3cde9fcea029558241850993a6ab5a
-    app.quarkus.io/build-timestamp: 2022-07-11 - 13:58:36 +0000
+    app.quarkus.io/commit-id: 665bca2f1245843e8c99eaa1a2c5315a6c002417
+    app.quarkus.io/build-timestamp: 2022-07-13 - 10:42:51 +0000
   labels:
     app: policyservice
     app.kubernetes.io/name: policyservice
@@ -39,8 +39,8 @@ spec:
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: fa8ec6157a3cde9fcea029558241850993a6ab5a
-        app.quarkus.io/build-timestamp: 2022-07-11 - 13:58:36 +0000
+        app.quarkus.io/commit-id: 665bca2f1245843e8c99eaa1a2c5315a6c002417
+        app.quarkus.io/build-timestamp: 2022-07-13 - 10:42:51 +0000
       labels:
         app: policyservice
         app.kubernetes.io/name: policyservice
@@ -51,10 +51,10 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
-            - name: SERVICE_SERVICE_HOST
-              value: serviceservice
             - name: CONTEXT_SERVICE_HOST
               value: contextservice
+            - name: SERVICE_SERVICE_HOST
+              value: serviceservice
             - name: MONITORING_SERVICE_HOST
               value: monitoringservice
           image: registry.gitlab.com/teraflow-h2020/controller/policy:0.1.0
@@ -71,12 +71,12 @@ spec:
             timeoutSeconds: 10
           name: policyservice
           ports:
+            - containerPort: 6060
+              name: grpc-server
+              protocol: TCP
             - containerPort: 8080
               name: http
               protocol: TCP
-            - containerPort: 9999
-              name: grpc-server
-              protocol: TCP
           readinessProbe:
             failureThreshold: 3
             httpGet:
-- 
GitLab


From 945026c5db81eff8a0030ff87b229f4116689951 Mon Sep 17 00:00:00 2001
From: Fotis Soldatos <fsoldatos@ubitech.eu>
Date: Wed, 13 Jul 2022 13:46:41 +0300
Subject: [PATCH 60/60] chore(automation): change gRPC port to 5050

---
 .../src/main/resources/application.yml        |  6 ++---
 .../target/kubernetes/kubernetes.yml          | 22 +++++++++----------
 2 files changed, 14 insertions(+), 14 deletions(-)

diff --git a/src/automation/src/main/resources/application.yml b/src/automation/src/main/resources/application.yml
index 24280803e..d61f3daa6 100644
--- a/src/automation/src/main/resources/application.yml
+++ b/src/automation/src/main/resources/application.yml
@@ -19,7 +19,7 @@ quarkus:
     path: teraflow-automation-banner.txt
   grpc:
     server:
-      port: 9999
+      port: 5050
       enable-reflection-service: true
     clients:
       context:
@@ -54,8 +54,8 @@ quarkus:
         host-port: 8080
         container-port: 8080
       grpc-server:
-        host-port: 9999
-        container-port: 9999
+        host-port: 5050
+        container-port: 5050
     env:
       vars:
         context-service-host: "contextservice"
diff --git a/src/automation/target/kubernetes/kubernetes.yml b/src/automation/target/kubernetes/kubernetes.yml
index 0e4bc0c62..68a7a59c2 100644
--- a/src/automation/target/kubernetes/kubernetes.yml
+++ b/src/automation/target/kubernetes/kubernetes.yml
@@ -3,8 +3,8 @@ apiVersion: v1
 kind: Service
 metadata:
   annotations:
-    app.quarkus.io/commit-id: fee580ca578000e6006c77704c0d6240e261de0f
-    app.quarkus.io/build-timestamp: 2022-05-27 - 08:02:36 +0000
+    app.quarkus.io/commit-id: 665bca2f1245843e8c99eaa1a2c5315a6c002417
+    app.quarkus.io/build-timestamp: 2022-07-13 - 10:46:17 +0000
   labels:
     app.kubernetes.io/name: automationservice
     app: automationservice
@@ -12,8 +12,8 @@ metadata:
 spec:
   ports:
     - name: grpc-server
-      port: 9999
-      targetPort: 9999
+      port: 5050
+      targetPort: 5050
     - name: http
       port: 8080
       targetPort: 8080
@@ -25,8 +25,8 @@ apiVersion: apps/v1
 kind: Deployment
 metadata:
   annotations:
-    app.quarkus.io/commit-id: fee580ca578000e6006c77704c0d6240e261de0f
-    app.quarkus.io/build-timestamp: 2022-05-27 - 08:02:36 +0000
+    app.quarkus.io/commit-id: 665bca2f1245843e8c99eaa1a2c5315a6c002417
+    app.quarkus.io/build-timestamp: 2022-07-13 - 10:46:17 +0000
   labels:
     app: automationservice
     app.kubernetes.io/name: automationservice
@@ -39,8 +39,8 @@ spec:
   template:
     metadata:
       annotations:
-        app.quarkus.io/commit-id: fee580ca578000e6006c77704c0d6240e261de0f
-        app.quarkus.io/build-timestamp: 2022-05-27 - 08:02:36 +0000
+        app.quarkus.io/commit-id: 665bca2f1245843e8c99eaa1a2c5315a6c002417
+        app.quarkus.io/build-timestamp: 2022-07-13 - 10:46:17 +0000
       labels:
         app: automationservice
         app.kubernetes.io/name: automationservice
@@ -51,10 +51,10 @@ spec:
               valueFrom:
                 fieldRef:
                   fieldPath: metadata.namespace
-            - name: CONTEXT_SERVICE_HOST
-              value: ContextService
             - name: DEVICE_SERVICE_HOST
               value: DeviceService
+            - name: CONTEXT_SERVICE_HOST
+              value: ContextService
           image: registry.gitlab.com/teraflow-h2020/controller/automation:0.2.0
           imagePullPolicy: Always
           livenessProbe:
@@ -69,7 +69,7 @@ spec:
             timeoutSeconds: 10
           name: automationservice
           ports:
-            - containerPort: 9999
+            - containerPort: 5050
               name: grpc-server
               protocol: TCP
             - containerPort: 8080
-- 
GitLab